From b73efee8f7bb60b72f1658a58001289214a2434c Mon Sep 17 00:00:00 2001 From: MrSubidubi Date: Tue, 26 May 2026 15:45:52 +0200 Subject: [PATCH 1/3] Clean up Component trait --- crates/agent_ui/src/ui/end_trial_upsell.rs | 19 +- crates/ai_onboarding/src/ai_onboarding.rs | 78 +-- crates/component/src/component.rs | 42 +- .../src/component_preview.rs | 151 ++--- crates/git_ui/src/git_panel.rs | 349 +++++----- crates/git_ui/src/git_ui.rs | 33 +- crates/language_models/src/provider/cloud.rs | 184 ++--- crates/notifications/src/status_toast.rs | 75 +-- crates/onboarding/src/theme_preview.rs | 82 ++- .../src/components/number_field.rs | 64 +- .../src/components/ai/agent_setup_button.rs | 17 +- .../ui/src/components/ai/ai_setting_item.rs | 9 +- .../src/components/ai/configured_api_card.rs | 9 +- crates/ui/src/components/ai/thread_item.rs | 15 +- crates/ui/src/components/avatar.rs | 12 +- crates/ui/src/components/banner.rs | 15 +- crates/ui/src/components/button/button.rs | 244 ++++--- .../ui/src/components/button/button_like.rs | 144 ++-- .../ui/src/components/button/button_link.rs | 28 +- .../ui/src/components/button/copy_button.rs | 8 +- .../ui/src/components/button/icon_button.rs | 313 ++++----- .../ui/src/components/button/toggle_button.rs | 573 +++++++--------- crates/ui/src/components/callout.rs | 23 +- crates/ui/src/components/chip.rs | 9 +- .../components/collab/collab_notification.rs | 21 +- .../ui/src/components/collab/update_button.rs | 75 +-- crates/ui/src/components/count_badge.rs | 40 +- crates/ui/src/components/data_table.rs | 196 +++--- crates/ui/src/components/diff_stat.rs | 15 +- crates/ui/src/components/disclosure.rs | 66 +- crates/ui/src/components/divider.rs | 145 ++-- crates/ui/src/components/dropdown_menu.rs | 117 ++-- crates/ui/src/components/facepile.rs | 67 +- crates/ui/src/components/icon.rs | 93 ++- .../ui/src/components/icon/decorated_icon.rs | 67 +- crates/ui/src/components/image.rs | 108 ++- crates/ui/src/components/indicator.rs | 161 +++-- crates/ui/src/components/keybinding.rs | 120 ++-- crates/ui/src/components/keybinding_hint.rs | 118 ++-- .../src/components/label/highlighted_label.rs | 169 ++--- crates/ui/src/components/label/label.rs | 11 +- crates/ui/src/components/label/label_like.rs | 13 +- .../ui/src/components/label/spinner_label.rs | 9 +- crates/ui/src/components/list/list.rs | 71 +- .../src/components/list/list_bullet_item.rs | 16 +- crates/ui/src/components/list/list_header.rs | 131 ++-- crates/ui/src/components/list/list_item.rs | 201 +++--- .../ui/src/components/list/list_sub_header.rs | 99 ++- .../components/notification/alert_modal.rs | 12 +- .../notification/announcement_toast.rs | 16 +- .../components/progress/circular_progress.rs | 75 +-- .../src/components/progress/progress_bar.rs | 84 ++- crates/ui/src/components/tab.rs | 91 ++- crates/ui/src/components/tab_bar.rs | 71 +- crates/ui/src/components/toggle.rs | 626 +++++++++--------- crates/ui/src/components/tooltip.rs | 25 +- crates/ui/src/components/tree_view_item.rs | 113 ++-- crates/ui/src/styles/animation.rs | 298 +++++---- crates/ui/src/styles/color.rs | 216 +++--- crates/ui/src/styles/typography.rs | 74 +-- crates/ui_input/src/input_field.rs | 36 +- crates/workspace/src/notifications.rs | 21 +- 62 files changed, 3096 insertions(+), 3287 deletions(-) diff --git a/crates/agent_ui/src/ui/end_trial_upsell.rs b/crates/agent_ui/src/ui/end_trial_upsell.rs index 1bf939522efd4d..ffca837b8f8ebc 100644 --- a/crates/agent_ui/src/ui/end_trial_upsell.rs +++ b/crates/agent_ui/src/ui/end_trial_upsell.rs @@ -103,13 +103,16 @@ impl Component for EndTrialUpsell { "End of Trial Upsell Banner" } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .child(EndTrialUpsell { - dismiss_upsell: Arc::new(|_, _| {}), - }) - .into_any_element(), - ) + fn description() -> &'static str { + "A banner shown in the agent panel when a user's trial has ended, \ + inviting them to upgrade to a paid plan to continue using the agent." + } + + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .child(EndTrialUpsell { + dismiss_upsell: Arc::new(|_, _| {}), + }) + .into_any_element() } } diff --git a/crates/ai_onboarding/src/ai_onboarding.rs b/crates/ai_onboarding/src/ai_onboarding.rs index 30aaa4206fe18d..30b022843c34da 100644 --- a/crates/ai_onboarding/src/ai_onboarding.rs +++ b/crates/ai_onboarding/src/ai_onboarding.rs @@ -376,7 +376,13 @@ impl Component for ZedAiOnboarding { "Agent New User Onboarding" } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { + fn description() -> &'static str { + "The onboarding surface shown to new agent panel users, \ + guiding them through signing in to Zed and selecting a plan \ + before they can start using the agent." + } + + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { fn onboarding( sign_in_status: SignInStatus, plan: Option, @@ -402,41 +408,39 @@ impl Component for ZedAiOnboarding { .into_any_element() } - Some( - v_flex() - .min_w_0() - .gap_4() - .children(vec![ - single_example( - "Not Signed-in", - onboarding(SignInStatus::SignedOut, None, false), - ), - single_example( - "Young Account", - onboarding(SignInStatus::SignedIn, None, true), - ), - single_example( - "Free Plan", - onboarding(SignInStatus::SignedIn, Some(Plan::ZedFree), false), - ), - single_example( - "Pro Trial", - onboarding(SignInStatus::SignedIn, Some(Plan::ZedProTrial), false), - ), - single_example( - "Pro Plan", - onboarding(SignInStatus::SignedIn, Some(Plan::ZedPro), false), - ), - single_example( - "Business Plan", - onboarding(SignInStatus::SignedIn, Some(Plan::ZedBusiness), false), - ), - single_example( - "Student Plan", - onboarding(SignInStatus::SignedIn, Some(Plan::ZedStudent), false), - ), - ]) - .into_any_element(), - ) + v_flex() + .min_w_0() + .gap_4() + .children(vec![ + single_example( + "Not Signed-in", + onboarding(SignInStatus::SignedOut, None, false), + ), + single_example( + "Young Account", + onboarding(SignInStatus::SignedIn, None, true), + ), + single_example( + "Free Plan", + onboarding(SignInStatus::SignedIn, Some(Plan::ZedFree), false), + ), + single_example( + "Pro Trial", + onboarding(SignInStatus::SignedIn, Some(Plan::ZedProTrial), false), + ), + single_example( + "Pro Plan", + onboarding(SignInStatus::SignedIn, Some(Plan::ZedPro), false), + ), + single_example( + "Business Plan", + onboarding(SignInStatus::SignedIn, Some(Plan::ZedBusiness), false), + ), + single_example( + "Student Plan", + onboarding(SignInStatus::SignedIn, Some(Plan::ZedStudent), false), + ), + ]) + .into_any_element() } } diff --git a/crates/component/src/component.rs b/crates/component/src/component.rs index 8c7b7ea4d7347f..abceb848dfe0ed 100644 --- a/crates/component/src/component.rs +++ b/crates/component/src/component.rs @@ -48,9 +48,9 @@ pub fn register_component() { let id = T::id(); let metadata = ComponentMetadata { id: id.clone(), - description: T::description().map(Into::into), + description: SharedString::new_static(T::description()), name: SharedString::new_static(T::name()), - preview: Some(T::preview), + preview: T::preview, scope: T::scope(), sort_name: SharedString::new_static(T::sort_name()), status: T::status(), @@ -69,15 +69,12 @@ pub struct ComponentRegistry { } impl ComponentRegistry { - pub fn previews(&self) -> Vec<&ComponentMetadata> { - self.components - .values() - .filter(|c| c.preview.is_some()) - .collect() + pub fn previews(&self) -> impl Iterator { + self.components.values() } pub fn sorted_previews(&self) -> Vec { - let mut previews: Vec = self.previews().into_iter().cloned().collect(); + let mut previews: Vec<_> = self.previews().cloned().collect(); previews.sort_by_key(|a| a.name()); previews } @@ -112,9 +109,9 @@ pub struct ComponentId(pub &'static str); #[derive(Clone)] pub struct ComponentMetadata { id: ComponentId, - description: Option, + description: SharedString, name: SharedString, - preview: Option Option>, + preview: fn(&mut Window, &mut App) -> AnyElement, scope: ComponentScope, sort_name: SharedString, status: ComponentStatus, @@ -125,7 +122,7 @@ impl ComponentMetadata { self.id.clone() } - pub fn description(&self) -> Option { + pub fn description(&self) -> SharedString { self.description.clone() } @@ -133,7 +130,7 @@ impl ComponentMetadata { self.name.clone() } - pub fn preview(&self) -> Option Option> { + pub fn preview(&self) -> fn(&mut Window, &mut App) -> AnyElement { self.preview } @@ -234,17 +231,15 @@ pub trait Component { /// struct MyComponent; /// /// impl MyComponent { - /// fn description() -> Option<&'static str> { - /// Some(Self::DOCS) + /// fn description() -> &'static str { + /// Self::DOCS /// } /// } /// ``` /// /// This will result in "This is a doc comment." being passed /// to the component's description. - fn description() -> Option<&'static str> { - None - } + fn description() -> &'static str; /// The component's preview. /// /// An element returned here will be shown in the component's preview. @@ -259,9 +254,7 @@ pub trait Component { /// This is useful for displaying related UI to the component you are /// trying to preview, such as a button that opens a modal or shows a /// tooltip on hover, or a grid of icons showcasing all the icons available. - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - None - } + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement; } /// The ready status of this component. @@ -286,14 +279,17 @@ impl ComponentStatus { pub fn description(&self) -> &str { match self { ComponentStatus::WorkInProgress => { - "These components are still being designed or refined. They shouldn't be used in the app yet." + "These components are still being designed or refined. \ + They shouldn't be used in the app yet." } ComponentStatus::EngineeringReady => { - "These components are design complete or partially implemented, and are ready for an engineer to complete their implementation." + "These components are design complete or partially implemented, \ + and are ready for an engineer to complete their implementation." } ComponentStatus::Live => "These components are ready for use in the app.", ComponentStatus::Deprecated => { - "These components are no longer recommended for use in the app, and may be removed in a future release." + "These components are no longer recommended for use in the app, \ + and may be removed in a future release." } } } diff --git a/crates/component_preview/src/component_preview.rs b/crates/component_preview/src/component_preview.rs index 27eb75a61995ed..1409105b12e05d 100644 --- a/crates/component_preview/src/component_preview.rs +++ b/crates/component_preview/src/component_preview.rs @@ -12,7 +12,10 @@ use notifications::status_toast::StatusToast; use persistence::ComponentPreviewDb; use project::Project; use std::{iter::Iterator, ops::Range, sync::Arc}; -use ui::{ButtonLike, Divider, HighlightedLabel, ListItem, ListSubHeader, Tooltip, prelude::*}; +use ui::{ + ButtonLike, Divider, HighlightedLabel, ListItem, ListSubHeader, Scrollbars, Tooltip, + WithScrollbar, prelude::*, +}; use ui_input::InputField; use workspace::AppState; use workspace::{ @@ -197,10 +200,7 @@ impl ComponentPreview { .filter(|component| { let component_name = component.name().to_lowercase(); let scope_name = component.scope().to_string().to_lowercase(); - let description = component - .description() - .map(|d| d.to_lowercase()) - .unwrap_or_default(); + let description = component.description().to_lowercase(); component_name.contains(&filter) || scope_name.contains(&filter) @@ -231,7 +231,7 @@ impl ComponentPreview { // let full_component_name = component.name(); let scopeless_name = component.scopeless_name(); let scope_name = component.scope().to_string(); - let description = component.description().unwrap_or_default(); + let description = component.description(); let lowercase_scopeless = scopeless_name.to_lowercase(); let lowercase_scope = scope_name.to_lowercase(); @@ -445,45 +445,40 @@ impl ComponentPreview { let description = component.description(); // Build the content container - let mut preview_container = v_flex().py_2().child( - v_flex() - .border_1() - .border_color(cx.theme().colors().border) - .rounded_sm() - .w_full() - .gap_4() - .py_4() - .px_6() - .flex_none() - .child( - v_flex() - .gap_1() - .child( - h_flex() - .gap_1() - .text_xl() - .child(div().child(name)) - .when(!matches!(scope, ComponentScope::None), |this| { - this.child(div().opacity(0.5).child(format!("({})", scope))) - }), - ) - .when_some(description, |this, description| { - this.child( + v_flex() + .py_2() + .child( + v_flex() + .border_1() + .border_color(cx.theme().colors().border) + .rounded_sm() + .w_full() + .gap_4() + .py_4() + .px_6() + .flex_none() + .child( + v_flex() + .gap_1() + .child( + h_flex().gap_1().text_xl().child(div().child(name)).when( + scope != ComponentScope::None, + |this| { + this.child(div().opacity(0.5).child(format!("({})", scope))) + }, + ), + ) + .child( div() .text_ui_sm(cx) .text_color(cx.theme().colors().text_muted) .max_w(px(600.0)) .child(description), - ) - }), - ), - ); - - if let Some(preview) = component.preview() { - preview_container = preview_container.children(preview(window, cx)); - } - - preview_container.into_any_element() + ), + ), + ) + .child((component.preview())(window, cx)) + .into_any_element() } fn render_all_components(&self, cx: &Context) -> impl IntoElement { @@ -593,6 +588,7 @@ impl Render for ComponentPreview { } let sidebar_entries = self.scope_ordered_entries(); let active_page = self.active_page.clone(); + let background_color = cx.theme().colors().editor_background; h_flex() .id("component-preview") @@ -601,37 +597,45 @@ impl Render for ComponentPreview { .overflow_hidden() .size_full() .track_focus(&self.focus_handle) - .bg(cx.theme().colors().editor_background) + .bg(background_color) .child( v_flex() .h_full() .border_r_1() .border_color(cx.theme().colors().border) .child( - gpui::uniform_list( - "component-nav", - sidebar_entries.len(), - cx.processor(move |this, range: Range, _window, cx| { - range - .filter_map(|ix| { - if ix < sidebar_entries.len() { - Some(this.render_sidebar_entry( - ix, - &sidebar_entries[ix], - cx, - )) - } else { - None - } - }) - .collect() - }), - ) - .track_scroll(&self.nav_scroll_handle) - .p_2p5() - .w(px(231.)) // Matches perfectly with the size of the "Component Preview" tab, if that's the first one in the pane - .h_full() - .flex_1(), + div() + .size_full() + .child( + gpui::uniform_list( + "component-nav", + sidebar_entries.len(), + cx.processor(move |this, range: Range, _window, cx| { + range + .filter(|ix| ix < &sidebar_entries.len()) + .map(|ix| { + this.render_sidebar_entry( + ix, + &sidebar_entries[ix], + cx, + ) + }) + .collect() + }), + ) + .track_scroll(&self.nav_scroll_handle) + .p_2p5() + .w(px(231.)) // Matches perfectly with the size of the "Component Preview" tab, if that's the first one in the pane + .h_full() + .flex_1(), + ) + .custom_scrollbars( + Scrollbars::new(ui::ScrollAxes::Vertical) + .with_track_along(ui::ScrollAxes::Vertical, background_color) + .tracked_scroll_handle(&self.nav_scroll_handle), + window, + cx, + ), ) .child( div() @@ -961,23 +965,10 @@ impl ComponentPreviewPage { .children(self.render_component_status(cx)), ), ) - .when_some(self.component.description(), |this, description| { - this.child(Label::new(description).size(LabelSize::Small)) - }) + .child(Label::new(self.component.description()).size(LabelSize::Small)) } fn render_preview(&self, window: &mut Window, cx: &mut App) -> impl IntoElement { - let content = if let Some(preview) = self.component.preview() { - // Fall back to component preview - preview(window, cx).unwrap_or_else(|| { - div() - .child("Failed to load preview. This path should be unreachable") - .into_any_element() - }) - } else { - div().child("No preview available").into_any_element() - }; - v_flex() .id(("component-preview", self.reset_key)) .size_full() @@ -985,7 +976,7 @@ impl ComponentPreviewPage { .px_12() .py_6() .bg(cx.theme().colors().editor_background) - .child(content) + .child((self.component.preview())(window, cx)) } } diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index 2618d84d93f360..46382ee2010801 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -7102,7 +7102,13 @@ impl Component for PanelRepoFooter { ComponentScope::VersionControl } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { + fn description() -> &'static str { + "The footer shown at the bottom of the git panel, \ + displaying the active repository, current branch, and \ + upstream tracking status alongside fetch, pull, and push controls." + } + + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { let unknown_upstream = None; let no_remote_upstream = Some(UpstreamTracking::Gone); let ahead_of_upstream = Some( @@ -7176,177 +7182,176 @@ impl Component for PanelRepoFooter { } let example_width = px(340.); - Some( - v_flex() - .gap_6() - .w_full() - .flex_none() - .children(vec![ - example_group_with_title( - "Action Button States", - vec![ - single_example( - "No Branch", - div() - .w(example_width) - .overflow_hidden() - .child(PanelRepoFooter::new_preview(active_repository(1), None)) - .into_any_element(), - ), - single_example( - "Remote status unknown", - div() - .w(example_width) - .overflow_hidden() - .child(PanelRepoFooter::new_preview( - active_repository(2), - Some(branch(unknown_upstream)), - )) - .into_any_element(), - ), - single_example( - "No Remote Upstream", - div() - .w(example_width) - .overflow_hidden() - .child(PanelRepoFooter::new_preview( - active_repository(3), - Some(branch(no_remote_upstream)), - )) - .into_any_element(), - ), - single_example( - "Not Ahead or Behind", - div() - .w(example_width) - .overflow_hidden() - .child(PanelRepoFooter::new_preview( - active_repository(4), - Some(branch(not_ahead_or_behind_upstream)), - )) - .into_any_element(), - ), - single_example( - "Behind remote", - div() - .w(example_width) - .overflow_hidden() - .child(PanelRepoFooter::new_preview( - active_repository(5), - Some(branch(behind_upstream)), - )) - .into_any_element(), - ), - single_example( - "Ahead of remote", - div() - .w(example_width) - .overflow_hidden() - .child(PanelRepoFooter::new_preview( - active_repository(6), - Some(branch(ahead_of_upstream)), - )) - .into_any_element(), - ), - single_example( - "Ahead and behind remote", - div() - .w(example_width) - .overflow_hidden() - .child(PanelRepoFooter::new_preview( - active_repository(7), - Some(branch(ahead_and_behind_upstream)), - )) - .into_any_element(), - ), - ], - ) - .grow() - .vertical(), - ]) - .children(vec![ - example_group_with_title( - "Labels", - vec![ - single_example( - "Short Branch & Repo", - div() - .w(example_width) - .overflow_hidden() - .child(PanelRepoFooter::new_preview( - SharedString::from("zed"), - Some(custom("main", behind_upstream)), - )) - .into_any_element(), - ), - single_example( - "Long Branch", - div() - .w(example_width) - .overflow_hidden() - .child(PanelRepoFooter::new_preview( - SharedString::from("zed"), - Some(custom( - "redesign-and-update-git-ui-list-entry-style", - behind_upstream, - )), - )) - .into_any_element(), - ), - single_example( - "Long Repo", - div() - .w(example_width) - .overflow_hidden() - .child(PanelRepoFooter::new_preview( - SharedString::from("zed-industries-community-examples"), - Some(custom("gpui", ahead_of_upstream)), - )) - .into_any_element(), - ), - single_example( - "Long Repo & Branch", - div() - .w(example_width) - .overflow_hidden() - .child(PanelRepoFooter::new_preview( - SharedString::from("zed-industries-community-examples"), - Some(custom( - "redesign-and-update-git-ui-list-entry-style", - behind_upstream, - )), - )) - .into_any_element(), - ), - single_example( - "Uppercase Repo", - div() - .w(example_width) - .overflow_hidden() - .child(PanelRepoFooter::new_preview( - SharedString::from("LICENSES"), - Some(custom("main", ahead_of_upstream)), - )) - .into_any_element(), - ), - single_example( - "Uppercase Branch", - div() - .w(example_width) - .overflow_hidden() - .child(PanelRepoFooter::new_preview( - SharedString::from("zed"), - Some(custom("update-README", behind_upstream)), - )) - .into_any_element(), - ), - ], - ) - .grow() - .vertical(), - ]) - .into_any_element(), - ) + + v_flex() + .gap_6() + .w_full() + .flex_none() + .children(vec![ + example_group_with_title( + "Action Button States", + vec![ + single_example( + "No Branch", + div() + .w(example_width) + .overflow_hidden() + .child(PanelRepoFooter::new_preview(active_repository(1), None)) + .into_any_element(), + ), + single_example( + "Remote status unknown", + div() + .w(example_width) + .overflow_hidden() + .child(PanelRepoFooter::new_preview( + active_repository(2), + Some(branch(unknown_upstream)), + )) + .into_any_element(), + ), + single_example( + "No Remote Upstream", + div() + .w(example_width) + .overflow_hidden() + .child(PanelRepoFooter::new_preview( + active_repository(3), + Some(branch(no_remote_upstream)), + )) + .into_any_element(), + ), + single_example( + "Not Ahead or Behind", + div() + .w(example_width) + .overflow_hidden() + .child(PanelRepoFooter::new_preview( + active_repository(4), + Some(branch(not_ahead_or_behind_upstream)), + )) + .into_any_element(), + ), + single_example( + "Behind remote", + div() + .w(example_width) + .overflow_hidden() + .child(PanelRepoFooter::new_preview( + active_repository(5), + Some(branch(behind_upstream)), + )) + .into_any_element(), + ), + single_example( + "Ahead of remote", + div() + .w(example_width) + .overflow_hidden() + .child(PanelRepoFooter::new_preview( + active_repository(6), + Some(branch(ahead_of_upstream)), + )) + .into_any_element(), + ), + single_example( + "Ahead and behind remote", + div() + .w(example_width) + .overflow_hidden() + .child(PanelRepoFooter::new_preview( + active_repository(7), + Some(branch(ahead_and_behind_upstream)), + )) + .into_any_element(), + ), + ], + ) + .grow() + .vertical(), + ]) + .children(vec![ + example_group_with_title( + "Labels", + vec![ + single_example( + "Short Branch & Repo", + div() + .w(example_width) + .overflow_hidden() + .child(PanelRepoFooter::new_preview( + SharedString::from("zed"), + Some(custom("main", behind_upstream)), + )) + .into_any_element(), + ), + single_example( + "Long Branch", + div() + .w(example_width) + .overflow_hidden() + .child(PanelRepoFooter::new_preview( + SharedString::from("zed"), + Some(custom( + "redesign-and-update-git-ui-list-entry-style", + behind_upstream, + )), + )) + .into_any_element(), + ), + single_example( + "Long Repo", + div() + .w(example_width) + .overflow_hidden() + .child(PanelRepoFooter::new_preview( + SharedString::from("zed-industries-community-examples"), + Some(custom("gpui", ahead_of_upstream)), + )) + .into_any_element(), + ), + single_example( + "Long Repo & Branch", + div() + .w(example_width) + .overflow_hidden() + .child(PanelRepoFooter::new_preview( + SharedString::from("zed-industries-community-examples"), + Some(custom( + "redesign-and-update-git-ui-list-entry-style", + behind_upstream, + )), + )) + .into_any_element(), + ), + single_example( + "Uppercase Repo", + div() + .w(example_width) + .overflow_hidden() + .child(PanelRepoFooter::new_preview( + SharedString::from("LICENSES"), + Some(custom("main", ahead_of_upstream)), + )) + .into_any_element(), + ), + single_example( + "Uppercase Branch", + div() + .w(example_width) + .overflow_hidden() + .child(PanelRepoFooter::new_preview( + SharedString::from("zed"), + Some(custom("update-README", behind_upstream)), + )) + .into_any_element(), + ), + ], + ) + .grow() + .vertical(), + ]) + .into_any_element() } } diff --git a/crates/git_ui/src/git_ui.rs b/crates/git_ui/src/git_ui.rs index f791ade8e0ca5d..d603cbdf579d67 100644 --- a/crates/git_ui/src/git_ui.rs +++ b/crates/git_ui/src/git_ui.rs @@ -1026,7 +1026,12 @@ impl Component for GitStatusIcon { ComponentScope::VersionControl } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { + fn description() -> &'static str { + "An icon that visually represents the git status of a file, \ + using a distinct glyph and color for modified, added, deleted, and conflicted states." + } + + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { fn tracked_file_status(code: StatusCode) -> FileStatus { FileStatus::Tracked(git::status::TrackedStatus { index_status: code, @@ -1043,20 +1048,18 @@ impl Component for GitStatusIcon { } .into(); - Some( - v_flex() - .gap_6() - .children(vec![example_group(vec![ - single_example("Modified", GitStatusIcon::new(modified).into_any_element()), - single_example("Added", GitStatusIcon::new(added).into_any_element()), - single_example("Deleted", GitStatusIcon::new(deleted).into_any_element()), - single_example( - "Conflicted", - GitStatusIcon::new(conflict).into_any_element(), - ), - ])]) - .into_any_element(), - ) + v_flex() + .gap_6() + .children(vec![example_group(vec![ + single_example("Modified", GitStatusIcon::new(modified).into_any_element()), + single_example("Added", GitStatusIcon::new(added).into_any_element()), + single_example("Deleted", GitStatusIcon::new(deleted).into_any_element()), + single_example( + "Conflicted", + GitStatusIcon::new(conflict).into_any_element(), + ), + ])]) + .into_any_element() } } diff --git a/crates/language_models/src/provider/cloud.rs b/crates/language_models/src/provider/cloud.rs index 3cb9fcf1b86975..bf8a1d857c74dc 100644 --- a/crates/language_models/src/provider/cloud.rs +++ b/crates/language_models/src/provider/cloud.rs @@ -665,7 +665,13 @@ impl Component for ZedAiConfiguration { ComponentScope::Onboarding } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { + fn description() -> &'static str { + "The configuration surface for Zed's hosted AI models, \ + showing the user's connection status, current plan, trial eligibility, \ + and entry points for enabling the Zed model provider." + } + + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { struct PreviewConfiguration { plan: Option, is_connected: bool, @@ -685,94 +691,92 @@ impl Component for ZedAiConfiguration { .into_any_element() }; - Some( - v_flex() - .p_4() - .gap_4() - .children(vec![ - single_example( - "Not connected", - configuration(PreviewConfiguration { - plan: None, - is_connected: false, - is_zed_model_provider_enabled: true, - eligible_for_trial: false, - }), - ), - single_example( - "Accept Terms of Service", - configuration(PreviewConfiguration { - plan: None, - is_connected: true, - is_zed_model_provider_enabled: true, - eligible_for_trial: true, - }), - ), - single_example( - "No Plan - Not eligible for trial", - configuration(PreviewConfiguration { - plan: None, - is_connected: true, - is_zed_model_provider_enabled: true, - eligible_for_trial: false, - }), - ), - single_example( - "No Plan - Eligible for trial", - configuration(PreviewConfiguration { - plan: None, - is_connected: true, - is_zed_model_provider_enabled: true, - eligible_for_trial: true, - }), - ), - single_example( - "Free Plan", - configuration(PreviewConfiguration { - plan: Some(Plan::ZedFree), - is_connected: true, - is_zed_model_provider_enabled: true, - eligible_for_trial: true, - }), - ), - single_example( - "Zed Pro Trial Plan", - configuration(PreviewConfiguration { - plan: Some(Plan::ZedProTrial), - is_connected: true, - is_zed_model_provider_enabled: true, - eligible_for_trial: true, - }), - ), - single_example( - "Zed Pro Plan", - configuration(PreviewConfiguration { - plan: Some(Plan::ZedPro), - is_connected: true, - is_zed_model_provider_enabled: true, - eligible_for_trial: true, - }), - ), - single_example( - "Business Plan - Zed models enabled", - configuration(PreviewConfiguration { - plan: Some(Plan::ZedBusiness), - is_connected: true, - is_zed_model_provider_enabled: true, - eligible_for_trial: false, - }), - ), - single_example( - "Business Plan - Zed models disabled", - configuration(PreviewConfiguration { - plan: Some(Plan::ZedBusiness), - is_connected: true, - is_zed_model_provider_enabled: false, - eligible_for_trial: false, - }), - ), - ]) - .into_any_element(), - ) + v_flex() + .p_4() + .gap_4() + .children(vec![ + single_example( + "Not connected", + configuration(PreviewConfiguration { + plan: None, + is_connected: false, + is_zed_model_provider_enabled: true, + eligible_for_trial: false, + }), + ), + single_example( + "Accept Terms of Service", + configuration(PreviewConfiguration { + plan: None, + is_connected: true, + is_zed_model_provider_enabled: true, + eligible_for_trial: true, + }), + ), + single_example( + "No Plan - Not eligible for trial", + configuration(PreviewConfiguration { + plan: None, + is_connected: true, + is_zed_model_provider_enabled: true, + eligible_for_trial: false, + }), + ), + single_example( + "No Plan - Eligible for trial", + configuration(PreviewConfiguration { + plan: None, + is_connected: true, + is_zed_model_provider_enabled: true, + eligible_for_trial: true, + }), + ), + single_example( + "Free Plan", + configuration(PreviewConfiguration { + plan: Some(Plan::ZedFree), + is_connected: true, + is_zed_model_provider_enabled: true, + eligible_for_trial: true, + }), + ), + single_example( + "Zed Pro Trial Plan", + configuration(PreviewConfiguration { + plan: Some(Plan::ZedProTrial), + is_connected: true, + is_zed_model_provider_enabled: true, + eligible_for_trial: true, + }), + ), + single_example( + "Zed Pro Plan", + configuration(PreviewConfiguration { + plan: Some(Plan::ZedPro), + is_connected: true, + is_zed_model_provider_enabled: true, + eligible_for_trial: true, + }), + ), + single_example( + "Business Plan - Zed models enabled", + configuration(PreviewConfiguration { + plan: Some(Plan::ZedBusiness), + is_connected: true, + is_zed_model_provider_enabled: true, + eligible_for_trial: false, + }), + ), + single_example( + "Business Plan - Zed models disabled", + configuration(PreviewConfiguration { + plan: Some(Plan::ZedBusiness), + is_connected: true, + is_zed_model_provider_enabled: false, + eligible_for_trial: false, + }), + ), + ]) + .into_any_element() } } diff --git a/crates/notifications/src/status_toast.rs b/crates/notifications/src/status_toast.rs index d9ffcddc6ffe65..e07cb99df5979c 100644 --- a/crates/notifications/src/status_toast.rs +++ b/crates/notifications/src/status_toast.rs @@ -150,7 +150,13 @@ impl Component for StatusToast { ComponentScope::Notification } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn description() -> &'static str { + "A compact, transient toast used to surface status updates \ + such as completed operations or pending updates, with optional icon, \ + action, and dismiss affordances." + } + + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let text_example = StatusToast::new("Operation completed", cx, |this, _| this); let action_example = StatusToast::new("Update ready to install", cx, |this, _cx| { @@ -214,44 +220,33 @@ impl Component for StatusToast { }) }); - Some( - v_flex() - .gap_6() - .p_4() - .children(vec![ - example_group_with_title( - "Basic Toast", - vec![ - single_example("Text", div().child(text_example).into_any_element()), - single_example( - "Action", - div().child(action_example).into_any_element(), - ), - single_example("Icon", div().child(icon_example).into_any_element()), - single_example( - "Dismiss Button", - div().child(dismiss_button_example).into_any_element(), - ), - ], - ), - example_group_with_title( - "Examples", - vec![ - single_example( - "Success", - div().child(success_example).into_any_element(), - ), - single_example("Error", div().child(error_example).into_any_element()), - single_example( - "Warning", - div().child(warning_example).into_any_element(), - ), - single_example("Create PR", div().child(pr_example).into_any_element()), - ], - ) - .vertical(), - ]) - .into_any_element(), - ) + v_flex() + .gap_6() + .p_4() + .children(vec![ + example_group_with_title( + "Basic Toast", + vec![ + single_example("Text", div().child(text_example).into_any_element()), + single_example("Action", div().child(action_example).into_any_element()), + single_example("Icon", div().child(icon_example).into_any_element()), + single_example( + "Dismiss Button", + div().child(dismiss_button_example).into_any_element(), + ), + ], + ), + example_group_with_title( + "Examples", + vec![ + single_example("Success", div().child(success_example).into_any_element()), + single_example("Error", div().child(error_example).into_any_element()), + single_example("Warning", div().child(warning_example).into_any_element()), + single_example("Create PR", div().child(pr_example).into_any_element()), + ], + ) + .vertical(), + ]) + .into_any_element() } } diff --git a/crates/onboarding/src/theme_preview.rs b/crates/onboarding/src/theme_preview.rs index 99990d1273f0c0..534272ecda8651 100644 --- a/crates/onboarding/src/theme_preview.rs +++ b/crates/onboarding/src/theme_preview.rs @@ -315,11 +315,11 @@ impl Component for ThemePreviewTile { "Theme Preview Tile" } - fn description() -> Option<&'static str> { - Some(Self::DOCS) + fn description() -> &'static str { + Self::DOCS } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let theme_registry = ThemeRegistry::global(cx); let one_dark = theme_registry.get("One Dark"); @@ -337,45 +337,43 @@ impl Component for ThemePreviewTile { .flatten() .collect::>(); - Some( - v_flex() - .gap_6() - .p_4() - .children({ - if let Some(one_dark) = one_dark.ok() { - vec![example_group(vec![single_example( - "Default", - div() - .w(px(240.)) - .h(px(180.)) - .child(ThemePreviewTile::new(one_dark, 0.42)) - .into_any_element(), - )])] - } else { - vec![] - } - }) - .child( - example_group(vec![single_example( - "Default Themes", - h_flex() - .gap_4() - .children( - themes_to_preview - .into_iter() - .map(|theme| { - div() - .w(px(200.)) - .h(px(140.)) - .child(ThemePreviewTile::new(theme, 0.42)) - }) - .collect::>(), - ) + v_flex() + .gap_6() + .p_4() + .children({ + if let Some(one_dark) = one_dark.ok() { + vec![example_group(vec![single_example( + "Default", + div() + .w(px(240.)) + .h(px(180.)) + .child(ThemePreviewTile::new(one_dark, 0.42)) .into_any_element(), - )]) - .grow(), - ) - .into_any_element(), - ) + )])] + } else { + vec![] + } + }) + .child( + example_group(vec![single_example( + "Default Themes", + h_flex() + .gap_4() + .children( + themes_to_preview + .into_iter() + .map(|theme| { + div() + .w(px(200.)) + .h(px(140.)) + .child(ThemePreviewTile::new(theme, 0.42)) + }) + .collect::>(), + ) + .into_any_element(), + )]) + .grow(), + ) + .into_any_element() } } diff --git a/crates/settings_ui/src/components/number_field.rs b/crates/settings_ui/src/components/number_field.rs index 9ddac4263e2e91..7ffec007fe6c22 100644 --- a/crates/settings_ui/src/components/number_field.rs +++ b/crates/settings_ui/src/components/number_field.rs @@ -727,43 +727,41 @@ impl Component for NumberField { "Number Field" } - fn description() -> Option<&'static str> { - Some("A numeric input element with increment and decrement buttons.") + fn description() -> &'static str { + "A numeric input element with increment and decrement buttons." } - fn preview(window: &mut Window, cx: &mut App) -> Option { + fn preview(window: &mut Window, cx: &mut App) -> AnyElement { let default_ex = window.use_state(cx, |_, _| 100.0); let edit_ex = window.use_state(cx, |_, _| 500.0); - Some( - v_flex() - .gap_6() - .children(vec![ - single_example( - "Button-Only Number Field", - NumberField::new("number-field", *default_ex.read(cx), window, cx) - .on_change({ - let default_ex = default_ex.clone(); - move |value, _, cx| default_ex.write(cx, *value) - }) - .min(1.0) - .max(100.0) - .into_any_element(), - ), - single_example( - "Editable Number Field", - NumberField::new("editable-number-field", *edit_ex.read(cx), window, cx) - .on_change({ - let edit_ex = edit_ex.clone(); - move |value, _, cx| edit_ex.write(cx, *value) - }) - .min(100.0) - .max(500.0) - .mode(NumberFieldMode::Edit, cx) - .into_any_element(), - ), - ]) - .into_any_element(), - ) + v_flex() + .gap_6() + .children(vec![ + single_example( + "Button-Only Number Field", + NumberField::new("number-field", *default_ex.read(cx), window, cx) + .on_change({ + let default_ex = default_ex.clone(); + move |value, _, cx| default_ex.write(cx, *value) + }) + .min(1.0) + .max(100.0) + .into_any_element(), + ), + single_example( + "Editable Number Field", + NumberField::new("editable-number-field", *edit_ex.read(cx), window, cx) + .on_change({ + let edit_ex = edit_ex.clone(); + move |value, _, cx| edit_ex.write(cx, *value) + }) + .min(100.0) + .max(500.0) + .mode(NumberFieldMode::Edit, cx) + .into_any_element(), + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/ai/agent_setup_button.rs b/crates/ui/src/components/ai/agent_setup_button.rs index d56baf91e1361d..c30add743b66dc 100644 --- a/crates/ui/src/components/ai/agent_setup_button.rs +++ b/crates/ui/src/components/ai/agent_setup_button.rs @@ -57,8 +57,21 @@ impl Component for AgentSetupButton { ComponentScope::Agent } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - None + fn description() -> &'static str { + "A large, two-section button used in agent onboarding flows \ + to launch the setup of a provider or tool, showing an icon, name, \ + and current setup state." + } + + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + single_example( + "Default", + AgentSetupButton::new("preview") + .icon(Icon::new(IconName::ZedAgent)) + .name("Zed Agent") + .into_any_element(), + ) + .into_any_element() } } diff --git a/crates/ui/src/components/ai/ai_setting_item.rs b/crates/ui/src/components/ai/ai_setting_item.rs index 6651ee1b769337..372ff75597dff7 100644 --- a/crates/ui/src/components/ai/ai_setting_item.rs +++ b/crates/ui/src/components/ai/ai_setting_item.rs @@ -244,7 +244,12 @@ impl Component for AiSettingItem { ComponentScope::Agent } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn description() -> &'static str { + "A reusable row used in AI-related configuration lists to display a \ + server or provider's name, source, current status, and associated actions." + } + + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let container = || { v_flex() .w_80() @@ -403,6 +408,6 @@ impl Component for AiSettingItem { ), ]; - Some(example_group(examples).vertical().into_any_element()) + example_group(examples).vertical().into_any_element() } } diff --git a/crates/ui/src/components/ai/configured_api_card.rs b/crates/ui/src/components/ai/configured_api_card.rs index c9fd129a678d00..9e89acc4962ef0 100644 --- a/crates/ui/src/components/ai/configured_api_card.rs +++ b/crates/ui/src/components/ai/configured_api_card.rs @@ -57,7 +57,12 @@ impl Component for ConfiguredApiCard { ComponentScope::Agent } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn description() -> &'static str { + "A card used in AI provider settings to indicate that an API has been \ + configured, with an optional action button to manage or reconfigure it." + } + + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let container = || { v_flex() .w_72() @@ -101,7 +106,7 @@ impl Component for ConfiguredApiCard { ), ]; - Some(example_group(examples).into_any_element()) + example_group(examples).into_any_element() } } diff --git a/crates/ui/src/components/ai/thread_item.rs b/crates/ui/src/components/ai/thread_item.rs index c962aa4f9f24e5..49ef0c7e0f6216 100644 --- a/crates/ui/src/components/ai/thread_item.rs +++ b/crates/ui/src/components/ai/thread_item.rs @@ -593,7 +593,12 @@ impl Component for ThreadItem { ComponentScope::Agent } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn description() -> &'static str { + "A row representing an agent thread in a list, showing its title, status, \ + timestamp, and contextual metadata such as worktree and branch information." + } + + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let color = cx.theme().colors(); let bg = color .title_bar_background @@ -930,10 +935,8 @@ impl Component for ThreadItem { ), ]; - Some( - example_group(thread_item_examples) - .vertical() - .into_any_element(), - ) + example_group(thread_item_examples) + .vertical() + .into_any_element() } } diff --git a/crates/ui/src/components/avatar.rs b/crates/ui/src/components/avatar.rs index 6ae969246f899e..6d12a0d3d226b0 100644 --- a/crates/ui/src/components/avatar.rs +++ b/crates/ui/src/components/avatar.rs @@ -235,15 +235,14 @@ impl Component for Avatar { ComponentScope::Collaboration } - fn description() -> Option<&'static str> { - Some(Avatar::DOCS) + fn description() -> &'static str { + Avatar::DOCS } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let example_avatar = "https://avatars.githubusercontent.com/u/1714999?v=4"; - Some( - v_flex() + v_flex() .gap_6() .children(vec![ example_group(vec![ @@ -297,7 +296,6 @@ impl Component for Avatar { ], ), ]) - .into_any_element(), - ) + .into_any_element() } } diff --git a/crates/ui/src/components/banner.rs b/crates/ui/src/components/banner.rs index 19795c2c7c8604..4568959a3734fa 100644 --- a/crates/ui/src/components/banner.rs +++ b/crates/ui/src/components/banner.rs @@ -134,7 +134,12 @@ impl Component for Banner { ComponentScope::DataDisplay } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { + fn description() -> &'static str { + "A non-blocking, severity-aware message strip used to surface informative, \ + success, warning, or error messages without interrupting the user." + } + + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { let severity_examples = vec![ single_example( "Default", @@ -179,10 +184,8 @@ impl Component for Banner { ), ]; - Some( - example_group(severity_examples) - .vertical() - .into_any_element(), - ) + example_group(severity_examples) + .vertical() + .into_any_element() } } diff --git a/crates/ui/src/components/button/button.rs b/crates/ui/src/components/button/button.rs index 61cb4a88556061..5278ffa2118cc2 100644 --- a/crates/ui/src/components/button/button.rs +++ b/crates/ui/src/components/button/button.rs @@ -448,130 +448,128 @@ impl Component for Button { "ButtonA" } - fn description() -> Option<&'static str> { - Some("A button triggers an event or action.") + fn description() -> &'static str { + "A button triggers an event or action." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Button Styles", - vec![ - single_example( - "Default", - Button::new("default", "Default").into_any_element(), - ), - single_example( - "Filled", - Button::new("filled", "Filled") - .style(ButtonStyle::Filled) - .into_any_element(), - ), - single_example( - "Subtle", - Button::new("outline", "Subtle") - .style(ButtonStyle::Subtle) - .into_any_element(), - ), - single_example( - "Tinted", - Button::new("tinted_accent_style", "Accent") - .style(ButtonStyle::Tinted(TintColor::Accent)) - .into_any_element(), - ), - single_example( - "Transparent", - Button::new("transparent", "Transparent") - .style(ButtonStyle::Transparent) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Tint Styles", - vec![ - single_example( - "Accent", - Button::new("tinted_accent", "Accent") - .style(ButtonStyle::Tinted(TintColor::Accent)) - .into_any_element(), - ), - single_example( - "Error", - Button::new("tinted_negative", "Error") - .style(ButtonStyle::Tinted(TintColor::Error)) - .into_any_element(), - ), - single_example( - "Warning", - Button::new("tinted_warning", "Warning") - .style(ButtonStyle::Tinted(TintColor::Warning)) - .into_any_element(), - ), - single_example( - "Success", - Button::new("tinted_positive", "Success") - .style(ButtonStyle::Tinted(TintColor::Success)) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Special States", - vec![ - single_example( - "Default", - Button::new("default_state", "Default").into_any_element(), - ), - single_example( - "Disabled", - Button::new("disabled", "Disabled") - .disabled(true) - .into_any_element(), - ), - single_example( - "Selected", - Button::new("selected", "Selected") - .toggle_state(true) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Buttons with Icons", - vec![ - single_example( - "Start Icon", - Button::new("icon_start", "Start Icon") - .start_icon(Icon::new(IconName::Check)) - .into_any_element(), - ), - single_example( - "End Icon", - Button::new("icon_end", "End Icon") - .end_icon(Icon::new(IconName::Check)) - .into_any_element(), - ), - single_example( - "Both Icons", - Button::new("both_icons", "Both Icons") - .start_icon(Icon::new(IconName::Check)) - .end_icon(Icon::new(IconName::ChevronDown)) - .into_any_element(), - ), - single_example( - "Icon Color", - Button::new("icon_color", "Icon Color") - .start_icon(Icon::new(IconName::Check).color(Color::Accent)) - .into_any_element(), - ), - ], - ), - ]) - .into_any_element(), - ) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Button Styles", + vec![ + single_example( + "Default", + Button::new("default", "Default").into_any_element(), + ), + single_example( + "Filled", + Button::new("filled", "Filled") + .style(ButtonStyle::Filled) + .into_any_element(), + ), + single_example( + "Subtle", + Button::new("outline", "Subtle") + .style(ButtonStyle::Subtle) + .into_any_element(), + ), + single_example( + "Tinted", + Button::new("tinted_accent_style", "Accent") + .style(ButtonStyle::Tinted(TintColor::Accent)) + .into_any_element(), + ), + single_example( + "Transparent", + Button::new("transparent", "Transparent") + .style(ButtonStyle::Transparent) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Tint Styles", + vec![ + single_example( + "Accent", + Button::new("tinted_accent", "Accent") + .style(ButtonStyle::Tinted(TintColor::Accent)) + .into_any_element(), + ), + single_example( + "Error", + Button::new("tinted_negative", "Error") + .style(ButtonStyle::Tinted(TintColor::Error)) + .into_any_element(), + ), + single_example( + "Warning", + Button::new("tinted_warning", "Warning") + .style(ButtonStyle::Tinted(TintColor::Warning)) + .into_any_element(), + ), + single_example( + "Success", + Button::new("tinted_positive", "Success") + .style(ButtonStyle::Tinted(TintColor::Success)) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Special States", + vec![ + single_example( + "Default", + Button::new("default_state", "Default").into_any_element(), + ), + single_example( + "Disabled", + Button::new("disabled", "Disabled") + .disabled(true) + .into_any_element(), + ), + single_example( + "Selected", + Button::new("selected", "Selected") + .toggle_state(true) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Buttons with Icons", + vec![ + single_example( + "Start Icon", + Button::new("icon_start", "Start Icon") + .start_icon(Icon::new(IconName::Check)) + .into_any_element(), + ), + single_example( + "End Icon", + Button::new("icon_end", "End Icon") + .end_icon(Icon::new(IconName::Check)) + .into_any_element(), + ), + single_example( + "Both Icons", + Button::new("both_icons", "Both Icons") + .start_icon(Icon::new(IconName::Check)) + .end_icon(Icon::new(IconName::ChevronDown)) + .into_any_element(), + ), + single_example( + "Icon Color", + Button::new("icon_color", "Icon Color") + .start_icon(Icon::new(IconName::Check).color(Color::Accent)) + .into_any_element(), + ), + ], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/button/button_like.rs b/crates/ui/src/components/button/button_like.rs index 2b0fa20683cce4..05999daef48acc 100644 --- a/crates/ui/src/components/button/button_like.rs +++ b/crates/ui/src/components/button/button_like.rs @@ -793,88 +793,86 @@ impl Component for ButtonLike { "ButtonZ" } - fn description() -> Option<&'static str> { - Some(ButtonLike::DOCS) - } - - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group(vec![ - single_example( - "Default", - ButtonLike::new("default") - .child(Label::new("Default")) - .into_any_element(), - ), + fn description() -> &'static str { + ButtonLike::DOCS + } + + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group(vec![ + single_example( + "Default", + ButtonLike::new("default") + .child(Label::new("Default")) + .into_any_element(), + ), + single_example( + "Filled", + ButtonLike::new("filled") + .style(ButtonStyle::Filled) + .child(Label::new("Filled")) + .into_any_element(), + ), + single_example( + "Subtle", + ButtonLike::new("outline") + .style(ButtonStyle::Subtle) + .child(Label::new("Subtle")) + .into_any_element(), + ), + single_example( + "Tinted", + ButtonLike::new("tinted_accent_style") + .style(ButtonStyle::Tinted(TintColor::Accent)) + .child(Label::new("Accent")) + .into_any_element(), + ), + single_example( + "Transparent", + ButtonLike::new("transparent") + .style(ButtonStyle::Transparent) + .child(Label::new("Transparent")) + .into_any_element(), + ), + ]), + example_group_with_title( + "Button Group Constructors", + vec![ single_example( - "Filled", - ButtonLike::new("filled") + "Left Rounded", + ButtonLike::new_rounded_left("left_rounded") + .child(Label::new("Left Rounded")) .style(ButtonStyle::Filled) - .child(Label::new("Filled")) .into_any_element(), ), single_example( - "Subtle", - ButtonLike::new("outline") - .style(ButtonStyle::Subtle) - .child(Label::new("Subtle")) - .into_any_element(), - ), - single_example( - "Tinted", - ButtonLike::new("tinted_accent_style") - .style(ButtonStyle::Tinted(TintColor::Accent)) - .child(Label::new("Accent")) + "Right Rounded", + ButtonLike::new_rounded_right("right_rounded") + .child(Label::new("Right Rounded")) + .style(ButtonStyle::Filled) .into_any_element(), ), single_example( - "Transparent", - ButtonLike::new("transparent") - .style(ButtonStyle::Transparent) - .child(Label::new("Transparent")) + "Button Group", + h_flex() + .gap_px() + .child( + ButtonLike::new_rounded_left("bg_left") + .child(Label::new("Left")) + .style(ButtonStyle::Filled), + ) + .child( + ButtonLike::new_rounded_right("bg_right") + .child(Label::new("Right")) + .style(ButtonStyle::Filled), + ) .into_any_element(), ), - ]), - example_group_with_title( - "Button Group Constructors", - vec![ - single_example( - "Left Rounded", - ButtonLike::new_rounded_left("left_rounded") - .child(Label::new("Left Rounded")) - .style(ButtonStyle::Filled) - .into_any_element(), - ), - single_example( - "Right Rounded", - ButtonLike::new_rounded_right("right_rounded") - .child(Label::new("Right Rounded")) - .style(ButtonStyle::Filled) - .into_any_element(), - ), - single_example( - "Button Group", - h_flex() - .gap_px() - .child( - ButtonLike::new_rounded_left("bg_left") - .child(Label::new("Left")) - .style(ButtonStyle::Filled), - ) - .child( - ButtonLike::new_rounded_right("bg_right") - .child(Label::new("Right")) - .style(ButtonStyle::Filled), - ) - .into_any_element(), - ), - ], - ), - ]) - .into_any_element(), - ) + ], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/button/button_link.rs b/crates/ui/src/components/button/button_link.rs index caffe2772bce39..841df96f555cca 100644 --- a/crates/ui/src/components/button/button_link.rs +++ b/crates/ui/src/components/button/button_link.rs @@ -81,22 +81,20 @@ impl Component for ButtonLink { ComponentScope::Navigation } - fn description() -> Option<&'static str> { - Some("A button that opens a URL.") + fn description() -> &'static str { + "A button that opens a URL." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .child( - example_group(vec![single_example( - "Simple", - ButtonLink::new("zed.dev", "https://zed.dev").into_any_element(), - )]) - .vertical(), - ) - .into_any_element(), - ) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .child( + example_group(vec![single_example( + "Simple", + ButtonLink::new("zed.dev", "https://zed.dev").into_any_element(), + )]) + .vertical(), + ) + .into_any_element() } } diff --git a/crates/ui/src/components/button/copy_button.rs b/crates/ui/src/components/button/copy_button.rs index c31d0eabbd669a..924d34e7c2f841 100644 --- a/crates/ui/src/components/button/copy_button.rs +++ b/crates/ui/src/components/button/copy_button.rs @@ -139,11 +139,11 @@ impl Component for CopyButton { ComponentScope::Input } - fn description() -> Option<&'static str> { - Some("An icon button that encapsulates the logic to copy a string into the clipboard.") + fn description() -> &'static str { + "An icon button that encapsulates the logic to copy a string into the clipboard." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { let label_text = "Here's an example label"; let examples = vec![ @@ -195,6 +195,6 @@ impl Component for CopyButton { ), ]; - Some(example_group(examples).vertical().into_any_element()) + example_group(examples).vertical().into_any_element() } } diff --git a/crates/ui/src/components/button/icon_button.rs b/crates/ui/src/components/button/icon_button.rs index a103ddf169a8ba..844bdb007e21ff 100644 --- a/crates/ui/src/components/button/icon_button.rs +++ b/crates/ui/src/components/button/icon_button.rs @@ -240,160 +240,163 @@ impl Component for IconButton { "ButtonB" } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Icon Button Styles", - vec![ - single_example( - "Default", - IconButton::new("default", IconName::Check) - .layer(ElevationIndex::Background) - .into_any_element(), - ), - single_example( - "Filled", - IconButton::new("filled", IconName::Check) - .layer(ElevationIndex::Background) - .style(ButtonStyle::Filled) - .into_any_element(), - ), - single_example( - "Subtle", - IconButton::new("subtle", IconName::Check) - .layer(ElevationIndex::Background) - .style(ButtonStyle::Subtle) - .into_any_element(), - ), - single_example( - "Tinted", - IconButton::new("tinted", IconName::Check) - .layer(ElevationIndex::Background) - .style(ButtonStyle::Tinted(TintColor::Accent)) - .into_any_element(), - ), - single_example( - "Transparent", - IconButton::new("transparent", IconName::Check) - .layer(ElevationIndex::Background) - .style(ButtonStyle::Transparent) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Icon Button Shapes", - vec![ - single_example( - "Square", - IconButton::new("square", IconName::Check) - .shape(IconButtonShape::Square) - .style(ButtonStyle::Filled) - .layer(ElevationIndex::Background) - .into_any_element(), - ), - single_example( - "Wide", - IconButton::new("wide", IconName::Check) - .shape(IconButtonShape::Wide) - .style(ButtonStyle::Filled) - .layer(ElevationIndex::Background) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Icon Button Sizes", - vec![ - single_example( - "XSmall", - IconButton::new("xsmall", IconName::Check) - .icon_size(IconSize::XSmall) - .style(ButtonStyle::Filled) - .layer(ElevationIndex::Background) - .into_any_element(), - ), - single_example( - "Small", - IconButton::new("small", IconName::Check) - .icon_size(IconSize::Small) - .style(ButtonStyle::Filled) - .layer(ElevationIndex::Background) - .into_any_element(), - ), - single_example( - "Medium", - IconButton::new("medium", IconName::Check) - .icon_size(IconSize::Medium) - .style(ButtonStyle::Filled) - .layer(ElevationIndex::Background) - .into_any_element(), - ), - single_example( - "XLarge", - IconButton::new("xlarge", IconName::Check) - .icon_size(IconSize::XLarge) - .style(ButtonStyle::Filled) - .layer(ElevationIndex::Background) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Special States", - vec![ - single_example( - "Disabled", - IconButton::new("disabled", IconName::Check) - .disabled(true) - .style(ButtonStyle::Filled) - .layer(ElevationIndex::Background) - .into_any_element(), - ), - single_example( - "Selected", - IconButton::new("selected", IconName::Check) - .toggle_state(true) - .style(ButtonStyle::Filled) - .layer(ElevationIndex::Background) - .into_any_element(), - ), - single_example( - "With Indicator", - IconButton::new("indicator", IconName::Check) - .indicator(Indicator::dot().color(Color::Success)) - .style(ButtonStyle::Filled) - .layer(ElevationIndex::Background) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Custom Colors", - vec![ - single_example( - "Custom Icon Color", - IconButton::new("custom_color", IconName::Check) - .icon_color(Color::Accent) - .style(ButtonStyle::Filled) - .layer(ElevationIndex::Background) - .into_any_element(), - ), - single_example( - "With Alpha", - IconButton::new("alpha", IconName::Check) - .alpha(0.5) - .style(ButtonStyle::Filled) - .layer(ElevationIndex::Background) - .into_any_element(), - ), - ], - ), - ]) - .into_any_element(), - ) + fn description() -> &'static str { + "A compact button that displays a single icon, used for actions where a \ + textual label would be redundant or take too much space." + } + + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Icon Button Styles", + vec![ + single_example( + "Default", + IconButton::new("default", IconName::Check) + .layer(ElevationIndex::Background) + .into_any_element(), + ), + single_example( + "Filled", + IconButton::new("filled", IconName::Check) + .layer(ElevationIndex::Background) + .style(ButtonStyle::Filled) + .into_any_element(), + ), + single_example( + "Subtle", + IconButton::new("subtle", IconName::Check) + .layer(ElevationIndex::Background) + .style(ButtonStyle::Subtle) + .into_any_element(), + ), + single_example( + "Tinted", + IconButton::new("tinted", IconName::Check) + .layer(ElevationIndex::Background) + .style(ButtonStyle::Tinted(TintColor::Accent)) + .into_any_element(), + ), + single_example( + "Transparent", + IconButton::new("transparent", IconName::Check) + .layer(ElevationIndex::Background) + .style(ButtonStyle::Transparent) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Icon Button Shapes", + vec![ + single_example( + "Square", + IconButton::new("square", IconName::Check) + .shape(IconButtonShape::Square) + .style(ButtonStyle::Filled) + .layer(ElevationIndex::Background) + .into_any_element(), + ), + single_example( + "Wide", + IconButton::new("wide", IconName::Check) + .shape(IconButtonShape::Wide) + .style(ButtonStyle::Filled) + .layer(ElevationIndex::Background) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Icon Button Sizes", + vec![ + single_example( + "XSmall", + IconButton::new("xsmall", IconName::Check) + .icon_size(IconSize::XSmall) + .style(ButtonStyle::Filled) + .layer(ElevationIndex::Background) + .into_any_element(), + ), + single_example( + "Small", + IconButton::new("small", IconName::Check) + .icon_size(IconSize::Small) + .style(ButtonStyle::Filled) + .layer(ElevationIndex::Background) + .into_any_element(), + ), + single_example( + "Medium", + IconButton::new("medium", IconName::Check) + .icon_size(IconSize::Medium) + .style(ButtonStyle::Filled) + .layer(ElevationIndex::Background) + .into_any_element(), + ), + single_example( + "XLarge", + IconButton::new("xlarge", IconName::Check) + .icon_size(IconSize::XLarge) + .style(ButtonStyle::Filled) + .layer(ElevationIndex::Background) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Special States", + vec![ + single_example( + "Disabled", + IconButton::new("disabled", IconName::Check) + .disabled(true) + .style(ButtonStyle::Filled) + .layer(ElevationIndex::Background) + .into_any_element(), + ), + single_example( + "Selected", + IconButton::new("selected", IconName::Check) + .toggle_state(true) + .style(ButtonStyle::Filled) + .layer(ElevationIndex::Background) + .into_any_element(), + ), + single_example( + "With Indicator", + IconButton::new("indicator", IconName::Check) + .indicator(Indicator::dot().color(Color::Success)) + .style(ButtonStyle::Filled) + .layer(ElevationIndex::Background) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Custom Colors", + vec![ + single_example( + "Custom Icon Color", + IconButton::new("custom_color", IconName::Check) + .icon_color(Color::Accent) + .style(ButtonStyle::Filled) + .layer(ElevationIndex::Background) + .into_any_element(), + ), + single_example( + "With Alpha", + IconButton::new("alpha", IconName::Check) + .alpha(0.5) + .style(ButtonStyle::Filled) + .layer(ElevationIndex::Background) + .into_any_element(), + ), + ], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/button/toggle_button.rs b/crates/ui/src/components/button/toggle_button.rs index 5cecfef0625648..395154cdf6e6bf 100644 --- a/crates/ui/src/components/button/toggle_button.rs +++ b/crates/ui/src/components/button/toggle_button.rs @@ -424,346 +424,241 @@ impl Component "ButtonG" } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![example_group_with_title( - "Transparent Variant", - vec![ - single_example( - "Single Row Group", - ToggleButtonGroup::single_row( - "single_row_test", - [ - ToggleButtonSimple::new("First", |_, _, _| {}), - ToggleButtonSimple::new("Second", |_, _, _| {}), - ToggleButtonSimple::new("Third", |_, _, _| {}), - ], - ) - .selected_index(1) - .into_any_element(), - ), - single_example( - "Single Row Group with icons", - ToggleButtonGroup::single_row( - "single_row_test_icon", - [ - ToggleButtonWithIcon::new( - "First", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Second", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Third", - IconName::AiZed, - |_, _, _| {}, - ), - ], - ) - .selected_index(1) - .into_any_element(), - ), - single_example( - "Multiple Row Group", - ToggleButtonGroup::two_rows( - "multiple_row_test", - [ - ToggleButtonSimple::new("First", |_, _, _| {}), - ToggleButtonSimple::new("Second", |_, _, _| {}), - ToggleButtonSimple::new("Third", |_, _, _| {}), - ], - [ - ToggleButtonSimple::new("Fourth", |_, _, _| {}), - ToggleButtonSimple::new("Fifth", |_, _, _| {}), - ToggleButtonSimple::new("Sixth", |_, _, _| {}), - ], - ) - .selected_index(3) - .into_any_element(), - ), - single_example( - "Multiple Row Group with Icons", - ToggleButtonGroup::two_rows( - "multiple_row_test_icons", - [ - ToggleButtonWithIcon::new( - "First", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Second", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Third", - IconName::AiZed, - |_, _, _| {}, - ), - ], - [ - ToggleButtonWithIcon::new( - "Fourth", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Fifth", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Sixth", - IconName::AiZed, - |_, _, _| {}, - ), - ], - ) - .selected_index(3) - .into_any_element(), - ), - ], - )]) - .children(vec![example_group_with_title( - "Outlined Variant", - vec![ - single_example( - "Single Row Group", - ToggleButtonGroup::single_row( - "single_row_test_outline", - [ - ToggleButtonSimple::new("First", |_, _, _| {}), - ToggleButtonSimple::new("Second", |_, _, _| {}), - ToggleButtonSimple::new("Third", |_, _, _| {}), - ], - ) - .selected_index(1) - .style(ToggleButtonGroupStyle::Outlined) - .into_any_element(), - ), - single_example( - "Single Row Group with icons", - ToggleButtonGroup::single_row( - "single_row_test_icon_outlined", - [ - ToggleButtonWithIcon::new( - "First", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Second", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Third", - IconName::AiZed, - |_, _, _| {}, - ), - ], - ) - .selected_index(1) - .style(ToggleButtonGroupStyle::Outlined) - .into_any_element(), - ), - single_example( - "Multiple Row Group", - ToggleButtonGroup::two_rows( - "multiple_row_test", - [ - ToggleButtonSimple::new("First", |_, _, _| {}), - ToggleButtonSimple::new("Second", |_, _, _| {}), - ToggleButtonSimple::new("Third", |_, _, _| {}), - ], - [ - ToggleButtonSimple::new("Fourth", |_, _, _| {}), - ToggleButtonSimple::new("Fifth", |_, _, _| {}), - ToggleButtonSimple::new("Sixth", |_, _, _| {}), - ], - ) - .selected_index(3) - .style(ToggleButtonGroupStyle::Outlined) - .into_any_element(), - ), - single_example( - "Multiple Row Group with Icons", - ToggleButtonGroup::two_rows( - "multiple_row_test", - [ - ToggleButtonWithIcon::new( - "First", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Second", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Third", - IconName::AiZed, - |_, _, _| {}, - ), - ], - [ - ToggleButtonWithIcon::new( - "Fourth", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Fifth", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Sixth", - IconName::AiZed, - |_, _, _| {}, - ), - ], - ) - .selected_index(3) - .style(ToggleButtonGroupStyle::Outlined) - .into_any_element(), - ), - ], - )]) - .children(vec![example_group_with_title( - "Filled Variant", - vec![ - single_example( - "Single Row Group", - ToggleButtonGroup::single_row( - "single_row_test_outline", - [ - ToggleButtonSimple::new("First", |_, _, _| {}), - ToggleButtonSimple::new("Second", |_, _, _| {}), - ToggleButtonSimple::new("Third", |_, _, _| {}), - ], - ) - .selected_index(2) - .style(ToggleButtonGroupStyle::Filled) - .into_any_element(), - ), - single_example( - "Single Row Group with icons", - ToggleButtonGroup::single_row( - "single_row_test_icon_outlined", - [ - ToggleButtonWithIcon::new( - "First", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Second", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Third", - IconName::AiZed, - |_, _, _| {}, - ), - ], - ) - .selected_index(1) - .style(ToggleButtonGroupStyle::Filled) - .into_any_element(), - ), - single_example( - "Multiple Row Group", - ToggleButtonGroup::two_rows( - "multiple_row_test", - [ - ToggleButtonSimple::new("First", |_, _, _| {}), - ToggleButtonSimple::new("Second", |_, _, _| {}), - ToggleButtonSimple::new("Third", |_, _, _| {}), - ], - [ - ToggleButtonSimple::new("Fourth", |_, _, _| {}), - ToggleButtonSimple::new("Fifth", |_, _, _| {}), - ToggleButtonSimple::new("Sixth", |_, _, _| {}), - ], - ) - .selected_index(3) - .width(rems_from_px(100.)) - .style(ToggleButtonGroupStyle::Filled) - .into_any_element(), - ), - single_example( - "Multiple Row Group with Icons", - ToggleButtonGroup::two_rows( - "multiple_row_test", - [ - ToggleButtonWithIcon::new( - "First", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Second", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Third", - IconName::AiZed, - |_, _, _| {}, - ), - ], - [ - ToggleButtonWithIcon::new( - "Fourth", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Fifth", - IconName::AiZed, - |_, _, _| {}, - ), - ToggleButtonWithIcon::new( - "Sixth", - IconName::AiZed, - |_, _, _| {}, - ), - ], - ) - .selected_index(3) - .width(rems_from_px(100.)) - .style(ToggleButtonGroupStyle::Filled) - .into_any_element(), - ), + fn description() -> &'static str { + "A grouped set of toggle buttons arranged in rows and columns, \ + where each button represents a mutually exclusive option in a segmented control." + } + + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![example_group_with_title( + "Transparent Variant", + vec![ + single_example( + "Single Row Group", + ToggleButtonGroup::single_row( + "single_row_test", + [ + ToggleButtonSimple::new("First", |_, _, _| {}), + ToggleButtonSimple::new("Second", |_, _, _| {}), + ToggleButtonSimple::new("Third", |_, _, _| {}), + ], + ) + .selected_index(1) + .into_any_element(), + ), + single_example( + "Single Row Group with icons", + ToggleButtonGroup::single_row( + "single_row_test_icon", + [ + ToggleButtonWithIcon::new("First", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Second", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Third", IconName::AiZed, |_, _, _| {}), + ], + ) + .selected_index(1) + .into_any_element(), + ), + single_example( + "Multiple Row Group", + ToggleButtonGroup::two_rows( + "multiple_row_test", + [ + ToggleButtonSimple::new("First", |_, _, _| {}), + ToggleButtonSimple::new("Second", |_, _, _| {}), + ToggleButtonSimple::new("Third", |_, _, _| {}), + ], + [ + ToggleButtonSimple::new("Fourth", |_, _, _| {}), + ToggleButtonSimple::new("Fifth", |_, _, _| {}), + ToggleButtonSimple::new("Sixth", |_, _, _| {}), + ], + ) + .selected_index(3) + .into_any_element(), + ), + single_example( + "Multiple Row Group with Icons", + ToggleButtonGroup::two_rows( + "multiple_row_test_icons", + [ + ToggleButtonWithIcon::new("First", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Second", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Third", IconName::AiZed, |_, _, _| {}), + ], + [ + ToggleButtonWithIcon::new("Fourth", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Fifth", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Sixth", IconName::AiZed, |_, _, _| {}), + ], + ) + .selected_index(3) + .into_any_element(), + ), + ], + )]) + .children(vec![example_group_with_title( + "Outlined Variant", + vec![ + single_example( + "Single Row Group", + ToggleButtonGroup::single_row( + "single_row_test_outline", + [ + ToggleButtonSimple::new("First", |_, _, _| {}), + ToggleButtonSimple::new("Second", |_, _, _| {}), + ToggleButtonSimple::new("Third", |_, _, _| {}), + ], + ) + .selected_index(1) + .style(ToggleButtonGroupStyle::Outlined) + .into_any_element(), + ), + single_example( + "Single Row Group with icons", + ToggleButtonGroup::single_row( + "single_row_test_icon_outlined", + [ + ToggleButtonWithIcon::new("First", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Second", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Third", IconName::AiZed, |_, _, _| {}), + ], + ) + .selected_index(1) + .style(ToggleButtonGroupStyle::Outlined) + .into_any_element(), + ), + single_example( + "Multiple Row Group", + ToggleButtonGroup::two_rows( + "multiple_row_test", + [ + ToggleButtonSimple::new("First", |_, _, _| {}), + ToggleButtonSimple::new("Second", |_, _, _| {}), + ToggleButtonSimple::new("Third", |_, _, _| {}), + ], + [ + ToggleButtonSimple::new("Fourth", |_, _, _| {}), + ToggleButtonSimple::new("Fifth", |_, _, _| {}), + ToggleButtonSimple::new("Sixth", |_, _, _| {}), + ], + ) + .selected_index(3) + .style(ToggleButtonGroupStyle::Outlined) + .into_any_element(), + ), + single_example( + "Multiple Row Group with Icons", + ToggleButtonGroup::two_rows( + "multiple_row_test", + [ + ToggleButtonWithIcon::new("First", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Second", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Third", IconName::AiZed, |_, _, _| {}), + ], + [ + ToggleButtonWithIcon::new("Fourth", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Fifth", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Sixth", IconName::AiZed, |_, _, _| {}), + ], + ) + .selected_index(3) + .style(ToggleButtonGroupStyle::Outlined) + .into_any_element(), + ), + ], + )]) + .children(vec![example_group_with_title( + "Filled Variant", + vec![ + single_example( + "Single Row Group", + ToggleButtonGroup::single_row( + "single_row_test_outline", + [ + ToggleButtonSimple::new("First", |_, _, _| {}), + ToggleButtonSimple::new("Second", |_, _, _| {}), + ToggleButtonSimple::new("Third", |_, _, _| {}), + ], + ) + .selected_index(2) + .style(ToggleButtonGroupStyle::Filled) + .into_any_element(), + ), + single_example( + "Single Row Group with icons", + ToggleButtonGroup::single_row( + "single_row_test_icon_outlined", + [ + ToggleButtonWithIcon::new("First", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Second", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Third", IconName::AiZed, |_, _, _| {}), + ], + ) + .selected_index(1) + .style(ToggleButtonGroupStyle::Filled) + .into_any_element(), + ), + single_example( + "Multiple Row Group", + ToggleButtonGroup::two_rows( + "multiple_row_test", + [ + ToggleButtonSimple::new("First", |_, _, _| {}), + ToggleButtonSimple::new("Second", |_, _, _| {}), + ToggleButtonSimple::new("Third", |_, _, _| {}), + ], + [ + ToggleButtonSimple::new("Fourth", |_, _, _| {}), + ToggleButtonSimple::new("Fifth", |_, _, _| {}), + ToggleButtonSimple::new("Sixth", |_, _, _| {}), + ], + ) + .selected_index(3) + .width(rems_from_px(100.)) + .style(ToggleButtonGroupStyle::Filled) + .into_any_element(), + ), + single_example( + "Multiple Row Group with Icons", + ToggleButtonGroup::two_rows( + "multiple_row_test", + [ + ToggleButtonWithIcon::new("First", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Second", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Third", IconName::AiZed, |_, _, _| {}), + ], + [ + ToggleButtonWithIcon::new("Fourth", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Fifth", IconName::AiZed, |_, _, _| {}), + ToggleButtonWithIcon::new("Sixth", IconName::AiZed, |_, _, _| {}), + ], + ) + .selected_index(3) + .width(rems_from_px(100.)) + .style(ToggleButtonGroupStyle::Filled) + .into_any_element(), + ), + ], + )]) + .children(vec![single_example( + "With Tooltips", + ToggleButtonGroup::single_row( + "with_tooltips", + [ + ToggleButtonSimple::new("First", |_, _, _| {}) + .tooltip(Tooltip::text("This is a tooltip. Hello!")), + ToggleButtonSimple::new("Second", |_, _, _| {}) + .tooltip(Tooltip::text("This is a tooltip. Hey?")), + ToggleButtonSimple::new("Third", |_, _, _| {}) + .tooltip(Tooltip::text("This is a tooltip. Get out of here now!")), ], - )]) - .children(vec![single_example( - "With Tooltips", - ToggleButtonGroup::single_row( - "with_tooltips", - [ - ToggleButtonSimple::new("First", |_, _, _| {}) - .tooltip(Tooltip::text("This is a tooltip. Hello!")), - ToggleButtonSimple::new("Second", |_, _, _| {}) - .tooltip(Tooltip::text("This is a tooltip. Hey?")), - ToggleButtonSimple::new("Third", |_, _, _| {}) - .tooltip(Tooltip::text("This is a tooltip. Get out of here now!")), - ], - ) - .selected_index(1) - .into_any_element(), - )]) + ) + .selected_index(1) .into_any_element(), - ) + )]) + .into_any_element() } } diff --git a/crates/ui/src/components/callout.rs b/crates/ui/src/components/callout.rs index 23c820cd545adf..9a897df1ac4541 100644 --- a/crates/ui/src/components/callout.rs +++ b/crates/ui/src/components/callout.rs @@ -224,13 +224,14 @@ impl Component for Callout { ComponentScope::DataDisplay } - fn description() -> Option<&'static str> { - Some( - "Used to display a callout for situations where the user needs to know some information, and likely make a decision. This might be a thread running out of tokens, or running out of prompts on a plan and needing to upgrade.", - ) + fn description() -> &'static str { + "Used to display a callout for situations where the user \ + needs to know some information, and likely make a decision. \ + This might be a thread running out of tokens, \ + or running out of prompts on a plan and needing to upgrade." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { let single_action = || Button::new("got-it", "Got it").label_size(LabelSize::Small); let multiple_actions = || { h_flex() @@ -354,12 +355,10 @@ impl Component for Callout { ), ]; - Some( - v_flex() - .gap_4() - .child(example_group(basic_examples).vertical()) - .child(example_group_with_title("Severity", severity_examples).vertical()) - .into_any_element(), - ) + v_flex() + .gap_4() + .child(example_group(basic_examples).vertical()) + .child(example_group_with_title("Severity", severity_examples).vertical()) + .into_any_element() } } diff --git a/crates/ui/src/components/chip.rs b/crates/ui/src/components/chip.rs index bcb21fb379c1d5..2609f2fc97b0ba 100644 --- a/crates/ui/src/components/chip.rs +++ b/crates/ui/src/components/chip.rs @@ -138,7 +138,12 @@ impl Component for Chip { ComponentScope::DataDisplay } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn description() -> &'static str { + "A small, compact label container used to display tags, statuses, \ + or other short informative pieces of metadata, optionally with an icon." + } + + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let chip_examples = vec![ single_example("Default", Chip::new("Chip Example").into_any_element()), single_example( @@ -162,6 +167,6 @@ impl Component for Chip { ), ]; - Some(example_group(chip_examples).vertical().into_any_element()) + example_group(chip_examples).vertical().into_any_element() } } diff --git a/crates/ui/src/components/collab/collab_notification.rs b/crates/ui/src/components/collab/collab_notification.rs index 28d28b0a292076..382749da37dbd5 100644 --- a/crates/ui/src/components/collab/collab_notification.rs +++ b/crates/ui/src/components/collab/collab_notification.rs @@ -63,7 +63,12 @@ impl Component for CollabNotification { ComponentScope::Collaboration } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { + fn description() -> &'static str { + "A toast-style notification surface for collaboration events, \ + such as incoming calls or shared project invites, with an accept and dismiss action." + } + + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { let avatar = "https://avatars.githubusercontent.com/u/67129314?v=4"; let container = || div().h(px(72.)).w(px(400.)); // Size of the actual notification window @@ -173,14 +178,10 @@ impl Component for CollabNotification { ), ]; - Some( - v_flex() - .gap_6() - .child(example_group_with_title("Calls & Projects", call_examples).vertical()) - .child( - example_group_with_title("Contact & Channel Toasts", toast_examples).vertical(), - ) - .into_any_element(), - ) + v_flex() + .gap_6() + .child(example_group_with_title("Calls & Projects", call_examples).vertical()) + .child(example_group_with_title("Contact & Channel Toasts", toast_examples).vertical()) + .into_any_element() } } diff --git a/crates/ui/src/components/collab/update_button.rs b/crates/ui/src/components/collab/update_button.rs index 56d7b0da1519fa..c0e74867cc62f7 100644 --- a/crates/ui/src/components/collab/update_button.rs +++ b/crates/ui/src/components/collab/update_button.rs @@ -172,48 +172,45 @@ impl Component for UpdateButton { "UpdateButton" } - fn description() -> Option<&'static str> { - Some( - "A button component displayed in the title bar to show auto-update status and allow users to restart Zed.", - ) + fn description() -> &'static str { + "A button component displayed in the title bar to \ + show auto-update status and allow users to restart Zed." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { let version = "1.3.0+stable.2025051"; - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Progress States", - vec![ - single_example("Checking", UpdateButton::checking().into_any_element()), - single_example( - "Downloading", - UpdateButton::downloading(version).into_any_element(), - ), - single_example( - "Installing", - UpdateButton::installing(version).into_any_element(), - ), - ], - ), - example_group_with_title( - "Actionable States", - vec![ - single_example( - "Ready to Update", - UpdateButton::updated(version).into_any_element(), - ), - single_example( - "Error", - UpdateButton::errored("Network timeout").into_any_element(), - ), - ], - ), - ]) - .into_any_element(), - ) + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Progress States", + vec![ + single_example("Checking", UpdateButton::checking().into_any_element()), + single_example( + "Downloading", + UpdateButton::downloading(version).into_any_element(), + ), + single_example( + "Installing", + UpdateButton::installing(version).into_any_element(), + ), + ], + ), + example_group_with_title( + "Actionable States", + vec![ + single_example( + "Ready to Update", + UpdateButton::updated(version).into_any_element(), + ), + single_example( + "Error", + UpdateButton::errored("Network timeout").into_any_element(), + ), + ], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/count_badge.rs b/crates/ui/src/components/count_badge.rs index c546d69e6d15b1..bf42e5c6fd3a88 100644 --- a/crates/ui/src/components/count_badge.rs +++ b/crates/ui/src/components/count_badge.rs @@ -57,11 +57,11 @@ impl Component for CountBadge { ComponentScope::Status } - fn description() -> Option<&'static str> { - Some("A small, pill-shaped badge that displays a numeric count.") + fn description() -> &'static str { + "A small, pill-shaped badge that displays a numeric count." } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let container = || { div() .relative() @@ -71,23 +71,21 @@ impl Component for CountBadge { .bg(cx.theme().colors().background) }; - Some( - v_flex() - .gap_6() - .child(example_group_with_title( - "Count Badge", - vec![ - single_example( - "Basic Count", - container().child(CountBadge::new(3)).into_any_element(), - ), - single_example( - "Capped Count", - container().child(CountBadge::new(150)).into_any_element(), - ), - ], - )) - .into_any_element(), - ) + v_flex() + .gap_6() + .child(example_group_with_title( + "Count Badge", + vec![ + single_example( + "Basic Count", + container().child(CountBadge::new(3)).into_any_element(), + ), + single_example( + "Capped Count", + container().child(CountBadge::new(150)).into_any_element(), + ), + ], + )) + .into_any_element() } } diff --git a/crates/ui/src/components/data_table.rs b/crates/ui/src/components/data_table.rs index 1700699a8750e6..42f6a9150fb106 100644 --- a/crates/ui/src/components/data_table.rs +++ b/crates/ui/src/components/data_table.rs @@ -1289,109 +1289,107 @@ impl Component for Table { ComponentScope::Layout } - fn description() -> Option<&'static str> { - Some("A table component for displaying data in rows and columns with optional styling.") + fn description() -> &'static str { + "A table component for displaying data in rows and columns with optional styling." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Basic Tables", - vec![ - single_example( - "Simple Table", - Table::new(3) - .width(px(400.)) - .header(vec!["Name", "Age", "City"]) - .row(vec!["Alice", "28", "New York"]) - .row(vec!["Bob", "32", "San Francisco"]) - .row(vec!["Charlie", "25", "London"]) - .into_any_element(), - ), - single_example( - "Two Column Table", - Table::new(2) - .header(vec!["Category", "Value"]) - .width(px(300.)) - .row(vec!["Revenue", "$100,000"]) - .row(vec!["Expenses", "$75,000"]) - .row(vec!["Profit", "$25,000"]) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Basic Tables", + vec![ + single_example( + "Simple Table", + Table::new(3) + .width(px(400.)) + .header(vec!["Name", "Age", "City"]) + .row(vec!["Alice", "28", "New York"]) + .row(vec!["Bob", "32", "San Francisco"]) + .row(vec!["Charlie", "25", "London"]) + .into_any_element(), + ), + single_example( + "Two Column Table", + Table::new(2) + .header(vec!["Category", "Value"]) + .width(px(300.)) + .row(vec!["Revenue", "$100,000"]) + .row(vec!["Expenses", "$75,000"]) + .row(vec!["Profit", "$25,000"]) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Styled Tables", + vec![ + single_example( + "Default", + Table::new(3) + .width(px(400.)) + .header(vec!["Product", "Price", "Stock"]) + .row(vec!["Laptop", "$999", "In Stock"]) + .row(vec!["Phone", "$599", "Low Stock"]) + .row(vec!["Tablet", "$399", "Out of Stock"]) + .into_any_element(), + ), + single_example( + "Striped", + Table::new(3) + .width(px(400.)) + .striped() + .header(vec!["Product", "Price", "Stock"]) + .row(vec!["Laptop", "$999", "In Stock"]) + .row(vec!["Phone", "$599", "Low Stock"]) + .row(vec!["Tablet", "$399", "Out of Stock"]) + .row(vec!["Headphones", "$199", "In Stock"]) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Mixed Content Table", + vec![single_example( + "Table with Elements", + Table::new(5) + .width(px(840.)) + .header(vec!["Status", "Name", "Priority", "Deadline", "Action"]) + .row(vec![ + Indicator::dot().color(Color::Success).into_any_element(), + "Project A".into_any_element(), + "High".into_any_element(), + "2023-12-31".into_any_element(), + Button::new("view_a", "View") + .style(ButtonStyle::Filled) + .full_width() .into_any_element(), - ), - ], - ), - example_group_with_title( - "Styled Tables", - vec![ - single_example( - "Default", - Table::new(3) - .width(px(400.)) - .header(vec!["Product", "Price", "Stock"]) - .row(vec!["Laptop", "$999", "In Stock"]) - .row(vec!["Phone", "$599", "Low Stock"]) - .row(vec!["Tablet", "$399", "Out of Stock"]) + ]) + .row(vec![ + Indicator::dot().color(Color::Warning).into_any_element(), + "Project B".into_any_element(), + "Medium".into_any_element(), + "2024-03-15".into_any_element(), + Button::new("view_b", "View") + .style(ButtonStyle::Filled) + .full_width() .into_any_element(), - ), - single_example( - "Striped", - Table::new(3) - .width(px(400.)) - .striped() - .header(vec!["Product", "Price", "Stock"]) - .row(vec!["Laptop", "$999", "In Stock"]) - .row(vec!["Phone", "$599", "Low Stock"]) - .row(vec!["Tablet", "$399", "Out of Stock"]) - .row(vec!["Headphones", "$199", "In Stock"]) + ]) + .row(vec![ + Indicator::dot().color(Color::Error).into_any_element(), + "Project C".into_any_element(), + "Low".into_any_element(), + "2024-06-30".into_any_element(), + Button::new("view_c", "View") + .style(ButtonStyle::Filled) + .full_width() .into_any_element(), - ), - ], - ), - example_group_with_title( - "Mixed Content Table", - vec![single_example( - "Table with Elements", - Table::new(5) - .width(px(840.)) - .header(vec!["Status", "Name", "Priority", "Deadline", "Action"]) - .row(vec![ - Indicator::dot().color(Color::Success).into_any_element(), - "Project A".into_any_element(), - "High".into_any_element(), - "2023-12-31".into_any_element(), - Button::new("view_a", "View") - .style(ButtonStyle::Filled) - .full_width() - .into_any_element(), - ]) - .row(vec![ - Indicator::dot().color(Color::Warning).into_any_element(), - "Project B".into_any_element(), - "Medium".into_any_element(), - "2024-03-15".into_any_element(), - Button::new("view_b", "View") - .style(ButtonStyle::Filled) - .full_width() - .into_any_element(), - ]) - .row(vec![ - Indicator::dot().color(Color::Error).into_any_element(), - "Project C".into_any_element(), - "Low".into_any_element(), - "2024-06-30".into_any_element(), - Button::new("view_c", "View") - .style(ButtonStyle::Filled) - .full_width() - .into_any_element(), - ]) - .into_any_element(), - )], - ), - ]) - .into_any_element(), - ) + ]) + .into_any_element(), + )], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/diff_stat.rs b/crates/ui/src/components/diff_stat.rs index 5fd88903470854..d6d644db4377f5 100644 --- a/crates/ui/src/components/diff_stat.rs +++ b/crates/ui/src/components/diff_stat.rs @@ -63,7 +63,12 @@ impl Component for DiffStat { ComponentScope::VersionControl } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn description() -> &'static str { + "A compact summary of additions and deletions for a diff, \ + displayed as colored insertion and deletion counts." + } + + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let container = || { h_flex() .py_4() @@ -81,10 +86,8 @@ impl Component for DiffStat { .into_any_element(), )]; - Some( - example_group(diff_stat_example) - .vertical() - .into_any_element(), - ) + example_group(diff_stat_example) + .vertical() + .into_any_element() } } diff --git a/crates/ui/src/components/disclosure.rs b/crates/ui/src/components/disclosure.rs index 320751890dab3a..09df75a5d5bc48 100644 --- a/crates/ui/src/components/disclosure.rs +++ b/crates/ui/src/components/disclosure.rs @@ -109,43 +109,37 @@ impl Component for Disclosure { ComponentScope::Input } - fn description() -> Option<&'static str> { - Some( - "An interactive element used to show or hide content, typically used in expandable sections or tree-like structures.", - ) + fn description() -> &'static str { + "An interactive element used to show or hide content, \ + typically used in expandable sections or tree-like structures." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Disclosure States", - vec![ - single_example( - "Closed", - Disclosure::new("closed", false).into_any_element(), - ), - single_example( - "Open", - Disclosure::new("open", true).into_any_element(), - ), - ], - ), - example_group_with_title( - "Interactive Example", - vec![single_example( - "Toggleable", - v_flex() - .gap_2() - .child(Disclosure::new("interactive", false).into_any_element()) - .child(Label::new("Click to toggle")) - .into_any_element(), - )], - ), - ]) - .into_any_element(), - ) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Disclosure States", + vec![ + single_example( + "Closed", + Disclosure::new("closed", false).into_any_element(), + ), + single_example("Open", Disclosure::new("open", true).into_any_element()), + ], + ), + example_group_with_title( + "Interactive Example", + vec![single_example( + "Toggleable", + v_flex() + .gap_2() + .child(Disclosure::new("interactive", false).into_any_element()) + .child(Label::new("Click to toggle")) + .into_any_element(), + )], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/divider.rs b/crates/ui/src/components/divider.rs index 5ad2187cfae36f..ff1f84adaa4daa 100644 --- a/crates/ui/src/components/divider.rs +++ b/crates/ui/src/components/divider.rs @@ -168,85 +168,76 @@ impl Component for Divider { ComponentScope::Layout } - fn description() -> Option<&'static str> { - Some( - "Visual separator used to create divisions between groups of content or sections in a layout.", - ) + fn description() -> &'static str { + "Visual separator used to create divisions between groups of content \ + or sections in a layout." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Horizontal Dividers", - vec![ - single_example("Default", Divider::horizontal().into_any_element()), - single_example( - "Border Color", - Divider::horizontal() - .color(DividerColor::Border) - .into_any_element(), - ), - single_example( - "Inset", - Divider::horizontal().inset().into_any_element(), - ), - single_example( - "Dashed", - Divider::horizontal_dashed().into_any_element(), - ), - ], - ), - example_group_with_title( - "Vertical Dividers", - vec![ - single_example( - "Default", - div().h_16().child(Divider::vertical()).into_any_element(), - ), - single_example( - "Border Color", - div() - .h_16() - .child(Divider::vertical().color(DividerColor::Border)) - .into_any_element(), - ), - single_example( - "Inset", - div() - .h_16() - .child(Divider::vertical().inset()) - .into_any_element(), - ), - single_example( - "Dashed", - div() - .h_16() - .child(Divider::vertical_dashed()) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Example Usage", - vec![single_example( - "Between Content", - v_flex() - .w_full() - .gap_4() - .px_4() - .child(Label::new("Section One")) - .child(Divider::horizontal()) - .child(Label::new("Section Two")) - .child(Divider::horizontal_dashed()) - .child(Label::new("Section Three")) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Horizontal Dividers", + vec![ + single_example("Default", Divider::horizontal().into_any_element()), + single_example( + "Border Color", + Divider::horizontal() + .color(DividerColor::Border) .into_any_element(), - )], - ), - ]) - .into_any_element(), - ) + ), + single_example("Inset", Divider::horizontal().inset().into_any_element()), + single_example("Dashed", Divider::horizontal_dashed().into_any_element()), + ], + ), + example_group_with_title( + "Vertical Dividers", + vec![ + single_example( + "Default", + div().h_16().child(Divider::vertical()).into_any_element(), + ), + single_example( + "Border Color", + div() + .h_16() + .child(Divider::vertical().color(DividerColor::Border)) + .into_any_element(), + ), + single_example( + "Inset", + div() + .h_16() + .child(Divider::vertical().inset()) + .into_any_element(), + ), + single_example( + "Dashed", + div() + .h_16() + .child(Divider::vertical_dashed()) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Example Usage", + vec![single_example( + "Between Content", + v_flex() + .w_full() + .gap_4() + .px_4() + .child(Label::new("Section One")) + .child(Divider::horizontal()) + .child(Label::new("Section Two")) + .child(Divider::horizontal_dashed()) + .child(Label::new("Section Three")) + .into_any_element(), + )], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/dropdown_menu.rs b/crates/ui/src/components/dropdown_menu.rs index c3cb3bcf0d5335..ebce559d7d4f5c 100644 --- a/crates/ui/src/components/dropdown_menu.rs +++ b/crates/ui/src/components/dropdown_menu.rs @@ -231,13 +231,12 @@ impl Component for DropdownMenu { "DropdownMenu" } - fn description() -> Option<&'static str> { - Some( - "A dropdown menu displays a list of actions or options. A dropdown menu is always activated by clicking a trigger (or via a keybinding).", - ) + fn description() -> &'static str { + "A dropdown menu displays a list of actions or options. \ + A dropdown menu is always activated by clicking a trigger (or via a keybinding)." } - fn preview(window: &mut Window, cx: &mut App) -> Option { + fn preview(window: &mut Window, cx: &mut App) -> AnyElement { let menu = ContextMenu::build(window, cx, |this, _, _| { this.entry("Option 1", None, |_, _| {}) .entry("Option 2", None, |_, _| {}) @@ -270,66 +269,60 @@ impl Component for DropdownMenu { }) }); - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Basic Usage", - vec![ - single_example( - "Default", - DropdownMenu::new("default", "Select an option", menu.clone()) - .into_any_element(), - ), - single_example( - "Full Width", - DropdownMenu::new( - "full-width", - "Full Width Dropdown", - menu.clone(), - ) + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Basic Usage", + vec![ + single_example( + "Default", + DropdownMenu::new("default", "Select an option", menu.clone()) + .into_any_element(), + ), + single_example( + "Full Width", + DropdownMenu::new("full-width", "Full Width Dropdown", menu.clone()) .full_width(true) .into_any_element(), - ), - ], - ), - example_group_with_title( - "Submenus", - vec![single_example( - "With Submenus", - DropdownMenu::new("submenu", "Submenu", menu_with_submenu) + ), + ], + ), + example_group_with_title( + "Submenus", + vec![single_example( + "With Submenus", + DropdownMenu::new("submenu", "Submenu", menu_with_submenu) + .into_any_element(), + )], + ), + example_group_with_title( + "Styles", + vec![ + single_example( + "Outlined", + DropdownMenu::new("outlined", "Outlined Dropdown", menu.clone()) + .style(DropdownStyle::Outlined) .into_any_element(), - )], - ), - example_group_with_title( - "Styles", - vec![ - single_example( - "Outlined", - DropdownMenu::new("outlined", "Outlined Dropdown", menu.clone()) - .style(DropdownStyle::Outlined) - .into_any_element(), - ), - single_example( - "Ghost", - DropdownMenu::new("ghost", "Ghost Dropdown", menu.clone()) - .style(DropdownStyle::Ghost) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "States", - vec![single_example( - "Disabled", - DropdownMenu::new("disabled", "Disabled Dropdown", menu) - .disabled(true) + ), + single_example( + "Ghost", + DropdownMenu::new("ghost", "Ghost Dropdown", menu.clone()) + .style(DropdownStyle::Ghost) .into_any_element(), - )], - ), - ]) - .into_any_element(), - ) + ), + ], + ), + example_group_with_title( + "States", + vec![single_example( + "Disabled", + DropdownMenu::new("disabled", "Disabled Dropdown", menu) + .disabled(true) + .into_any_element(), + )], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/facepile.rs b/crates/ui/src/components/facepile.rs index 79a36871d60180..4960cb986010be 100644 --- a/crates/ui/src/components/facepile.rs +++ b/crates/ui/src/components/facepile.rs @@ -94,42 +94,39 @@ impl Component for Facepile { ComponentScope::Collaboration } - fn description() -> Option<&'static str> { - Some( - "Displays a collection of avatars or initials in a compact format. Often used to represent active collaborators or a subset of contributors.", - ) + fn description() -> &'static str { + "Displays a collection of avatars or initials in a compact format. \ + Often used to represent active collaborators or a subset of contributors." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![example_group_with_title( - "Facepile Examples", - vec![ - single_example( - "Default", - Facepile::new( - EXAMPLE_FACES - .iter() - .map(|&url| Avatar::new(url).into_any_element()) - .collect(), - ) - .into_any_element(), - ), - single_example( - "Custom Size", - Facepile::new( - EXAMPLE_FACES - .iter() - .map(|&url| Avatar::new(url).size(px(24.)).into_any_element()) - .collect(), - ) - .into_any_element(), - ), - ], - )]) - .into_any_element(), - ) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![example_group_with_title( + "Facepile Examples", + vec![ + single_example( + "Default", + Facepile::new( + EXAMPLE_FACES + .iter() + .map(|&url| Avatar::new(url).into_any_element()) + .collect(), + ) + .into_any_element(), + ), + single_example( + "Custom Size", + Facepile::new( + EXAMPLE_FACES + .iter() + .map(|&url| Avatar::new(url).size(px(24.)).into_any_element()) + .collect(), + ) + .into_any_element(), + ), + ], + )]) + .into_any_element() } } diff --git a/crates/ui/src/components/icon.rs b/crates/ui/src/components/icon.rs index d9a1553b7da442..6089bba4b86f47 100644 --- a/crates/ui/src/components/icon.rs +++ b/crates/ui/src/components/icon.rs @@ -288,57 +288,54 @@ impl Component for Icon { ComponentScope::Images } - fn description() -> Option<&'static str> { - Some( - "A versatile icon component that supports SVG and image-based icons with customizable size, color, and transformations.", - ) + fn description() -> &'static str { + "A versatile icon component that supports SVG and image-based icons \ + with customizable size, color, and transformations." } - fn preview(_window: &mut Window, cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Sizes", - vec![single_example( - "XSmall, Small, Default, Large", - h_flex() - .gap_1() - .child(Icon::new(IconName::Star).size(IconSize::XSmall)) - .child(Icon::new(IconName::Star).size(IconSize::Small)) - .child(Icon::new(IconName::Star)) - .child(Icon::new(IconName::Star).size(IconSize::XLarge)) - .into_any_element(), - )], - ), - example_group(vec![single_example( - "All Icons", + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Sizes", + vec![single_example( + "XSmall, Small, Default, Large", h_flex() - .image_cache(gpui::retain_all("all icons")) - .flex_wrap() - .gap_2() - .children(::iter().map( - |icon_name: IconName| { - let name: SharedString = format!("{icon_name:?}").into(); - v_flex() - .min_w_0() - .w_24() - .p_1p5() - .gap_2() - .border_1() - .border_color(cx.theme().colors().border_variant) - .bg(cx.theme().colors().element_disabled) - .rounded_sm() - .items_center() - .child(Icon::new(icon_name)) - .child(Label::new(name).size(LabelSize::XSmall).truncate()) - }, - )) + .gap_1() + .child(Icon::new(IconName::Star).size(IconSize::XSmall)) + .child(Icon::new(IconName::Star).size(IconSize::Small)) + .child(Icon::new(IconName::Star)) + .child(Icon::new(IconName::Star).size(IconSize::XLarge)) .into_any_element(), - )]), - ]) - .into_any_element(), - ) + )], + ), + example_group(vec![single_example( + "All Icons", + h_flex() + .image_cache(gpui::retain_all("all icons")) + .flex_wrap() + .gap_2() + .children(::iter().map( + |icon_name: IconName| { + let name: SharedString = format!("{icon_name:?}").into(); + v_flex() + .min_w_0() + .w_24() + .p_1p5() + .gap_2() + .border_1() + .border_color(cx.theme().colors().border_variant) + .bg(cx.theme().colors().element_disabled) + .rounded_sm() + .items_center() + .child(Icon::new(icon_name)) + .child(Label::new(name).size(LabelSize::XSmall).truncate()) + }, + )) + .into_any_element(), + )]), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/icon/decorated_icon.rs b/crates/ui/src/components/icon/decorated_icon.rs index 82ca844c384b5a..5ea8cdc48e4a4a 100644 --- a/crates/ui/src/components/icon/decorated_icon.rs +++ b/crates/ui/src/components/icon/decorated_icon.rs @@ -29,13 +29,12 @@ impl Component for DecoratedIcon { ComponentScope::Images } - fn description() -> Option<&'static str> { - Some( - "An icon with an optional decoration overlay (like an X, triangle, or dot) that can be positioned relative to the icon", - ) + fn description() -> &'static str { + "An icon with an optional decoration overlay (like an X, triangle, or dot) \ + that can be positioned relative to the icon" } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let decoration_x = IconDecoration::new( IconDecorationKind::X, cx.theme().colors().surface_background, @@ -69,38 +68,32 @@ impl Component for DecoratedIcon { y: px(-2.), }); - Some( - v_flex() - .gap_6() - .children(vec![example_group_with_title( - "Decorations", - vec![ - single_example( - "No Decoration", - DecoratedIcon::new(Icon::new(IconName::FileDoc), None) - .into_any_element(), - ), - single_example( - "X Decoration", - DecoratedIcon::new(Icon::new(IconName::FileDoc), Some(decoration_x)) - .into_any_element(), - ), - single_example( - "Triangle Decoration", - DecoratedIcon::new( - Icon::new(IconName::FileDoc), - Some(decoration_triangle), - ) + v_flex() + .gap_6() + .children(vec![example_group_with_title( + "Decorations", + vec![ + single_example( + "No Decoration", + DecoratedIcon::new(Icon::new(IconName::FileDoc), None).into_any_element(), + ), + single_example( + "X Decoration", + DecoratedIcon::new(Icon::new(IconName::FileDoc), Some(decoration_x)) .into_any_element(), - ), - single_example( - "Dot Decoration", - DecoratedIcon::new(Icon::new(IconName::FileDoc), Some(decoration_dot)) - .into_any_element(), - ), - ], - )]) - .into_any_element(), - ) + ), + single_example( + "Triangle Decoration", + DecoratedIcon::new(Icon::new(IconName::FileDoc), Some(decoration_triangle)) + .into_any_element(), + ), + single_example( + "Dot Decoration", + DecoratedIcon::new(Icon::new(IconName::FileDoc), Some(decoration_dot)) + .into_any_element(), + ), + ], + )]) + .into_any_element() } } diff --git a/crates/ui/src/components/image.rs b/crates/ui/src/components/image.rs index 759d637d451da5..25b1a3003f400b 100644 --- a/crates/ui/src/components/image.rs +++ b/crates/ui/src/components/image.rs @@ -106,66 +106,64 @@ impl Component for Vector { "Vector" } - fn description() -> Option<&'static str> { - Some("A vector image component that can be displayed at specific sizes.") + fn description() -> &'static str { + "A vector image component that can be displayed at specific sizes." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { let size = rems_from_px(60.); - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Basic Usage", - vec![ - single_example( - "Default", - Vector::square(VectorName::ZedLogo, size).into_any_element(), - ), - single_example( - "Custom Size", - h_flex() - .h(rems_from_px(120.)) - .justify_center() - .child(Vector::new( - VectorName::ZedLogo, - rems_from_px(120.), - rems_from_px(200.), - )) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Colored", - vec![ - single_example( - "Accent Color", - Vector::square(VectorName::ZedLogo, size) - .color(Color::Accent) - .into_any_element(), - ), - single_example( - "Error Color", - Vector::square(VectorName::ZedLogo, size) - .color(Color::Error) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Different Vectors", - vec![single_example( - "Zed X Copilot", - Vector::square(VectorName::ZedXCopilot, rems_from_px(100.)) + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Basic Usage", + vec![ + single_example( + "Default", + Vector::square(VectorName::ZedLogo, size).into_any_element(), + ), + single_example( + "Custom Size", + h_flex() + .h(rems_from_px(120.)) + .justify_center() + .child(Vector::new( + VectorName::ZedLogo, + rems_from_px(120.), + rems_from_px(200.), + )) .into_any_element(), - )], - ), - ]) - .into_any_element(), - ) + ), + ], + ), + example_group_with_title( + "Colored", + vec![ + single_example( + "Accent Color", + Vector::square(VectorName::ZedLogo, size) + .color(Color::Accent) + .into_any_element(), + ), + single_example( + "Error Color", + Vector::square(VectorName::ZedLogo, size) + .color(Color::Error) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Different Vectors", + vec![single_example( + "Zed X Copilot", + Vector::square(VectorName::ZedXCopilot, rems_from_px(100.)) + .into_any_element(), + )], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/indicator.rs b/crates/ui/src/components/indicator.rs index 59d69a068b3955..41f6f6766854a8 100644 --- a/crates/ui/src/components/indicator.rs +++ b/crates/ui/src/components/indicator.rs @@ -89,89 +89,86 @@ impl Component for Indicator { ComponentScope::Status } - fn description() -> Option<&'static str> { - Some( - "Visual indicators used to represent status, notifications, or draw attention to specific elements.", - ) + fn description() -> &'static str { + "Visual indicators used to represent status, notifications, \ + or draw attention to specific elements." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Dot Indicators", - vec![ - single_example("Default", Indicator::dot().into_any_element()), - single_example( - "Success", - Indicator::dot().color(Color::Success).into_any_element(), - ), - single_example( - "Warning", - Indicator::dot().color(Color::Warning).into_any_element(), - ), - single_example( - "Error", - Indicator::dot().color(Color::Error).into_any_element(), - ), - single_example( - "With Border", - Indicator::dot() - .color(Color::Accent) - .border_color(Color::Default) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Bar Indicators", - vec![ - single_example("Default", Indicator::bar().into_any_element()), - single_example( - "Success", - Indicator::bar().color(Color::Success).into_any_element(), - ), - single_example( - "Warning", - Indicator::bar().color(Color::Warning).into_any_element(), - ), - single_example( - "Error", - Indicator::bar().color(Color::Error).into_any_element(), - ), - ], - ), - example_group_with_title( - "Icon Indicators", - vec![ - single_example( - "Default", - Indicator::icon(Icon::new(IconName::Circle)).into_any_element(), - ), - single_example( - "Success", - Indicator::icon(Icon::new(IconName::Check)) - .color(Color::Success) - .into_any_element(), - ), - single_example( - "Warning", - Indicator::icon(Icon::new(IconName::Warning)) - .color(Color::Warning) - .into_any_element(), - ), - single_example( - "Error", - Indicator::icon(Icon::new(IconName::Close)) - .color(Color::Error) - .into_any_element(), - ), - ], - ), - ]) - .into_any_element(), - ) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Dot Indicators", + vec![ + single_example("Default", Indicator::dot().into_any_element()), + single_example( + "Success", + Indicator::dot().color(Color::Success).into_any_element(), + ), + single_example( + "Warning", + Indicator::dot().color(Color::Warning).into_any_element(), + ), + single_example( + "Error", + Indicator::dot().color(Color::Error).into_any_element(), + ), + single_example( + "With Border", + Indicator::dot() + .color(Color::Accent) + .border_color(Color::Default) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Bar Indicators", + vec![ + single_example("Default", Indicator::bar().into_any_element()), + single_example( + "Success", + Indicator::bar().color(Color::Success).into_any_element(), + ), + single_example( + "Warning", + Indicator::bar().color(Color::Warning).into_any_element(), + ), + single_example( + "Error", + Indicator::bar().color(Color::Error).into_any_element(), + ), + ], + ), + example_group_with_title( + "Icon Indicators", + vec![ + single_example( + "Default", + Indicator::icon(Icon::new(IconName::Circle)).into_any_element(), + ), + single_example( + "Success", + Indicator::icon(Icon::new(IconName::Check)) + .color(Color::Success) + .into_any_element(), + ), + single_example( + "Warning", + Indicator::icon(Icon::new(IconName::Warning)) + .color(Color::Warning) + .into_any_element(), + ), + single_example( + "Error", + Indicator::icon(Icon::new(IconName::Close)) + .color(Color::Error) + .into_any_element(), + ), + ], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/keybinding.rs b/crates/ui/src/components/keybinding.rs index 016181ee9bd22a..eaf0de1e602fff 100644 --- a/crates/ui/src/components/keybinding.rs +++ b/crates/ui/src/components/keybinding.rs @@ -563,85 +563,49 @@ impl Component for KeyBinding { "KeyBinding" } - fn description() -> Option<&'static str> { - Some( - "A component that displays a key binding, supporting different platform styles and vim mode.", - ) - } + fn description() -> &'static str { + "A component that displays a key binding, \ + supporting different platform styles and vim mode." + } + + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + fn keybinding(input: &str) -> KeyBinding { + let keystrokes: Rc<[KeybindingKeystroke]> = input + .split_whitespace() + .filter_map(|chunk| Keystroke::parse(chunk).ok()) + .map(KeybindingKeystroke::from_keystroke) + .collect::>() + .into(); + KeyBinding::from_keystrokes(keystrokes, false) + } - // fn preview(_window: &mut Window, cx: &mut App) -> Option { - // Some( - // v_flex() - // .gap_6() - // .children(vec![ - // example_group_with_title( - // "Basic Usage", - // vec![ - // single_example( - // "Default", - // KeyBinding::new_from_gpui( - // gpui::KeyBinding::new("ctrl-s", gpui::NoAction, None), - // cx, - // ) - // .into_any_element(), - // ), - // single_example( - // "Mac Style", - // KeyBinding::new_from_gpui( - // gpui::KeyBinding::new("cmd-s", gpui::NoAction, None), - // cx, - // ) - // .platform_style(PlatformStyle::Mac) - // .into_any_element(), - // ), - // single_example( - // "Windows Style", - // KeyBinding::new_from_gpui( - // gpui::KeyBinding::new("ctrl-s", gpui::NoAction, None), - // cx, - // ) - // .platform_style(PlatformStyle::Windows) - // .into_any_element(), - // ), - // ], - // ), - // example_group_with_title( - // "Vim Mode", - // vec![single_example( - // "Vim Mode Enabled", - // KeyBinding::new_from_gpui( - // gpui::KeyBinding::new("dd", gpui::NoAction, None), - // cx, - // ) - // .vim_mode(true) - // .into_any_element(), - // )], - // ), - // example_group_with_title( - // "Complex Bindings", - // vec![ - // single_example( - // "Multiple Keys", - // KeyBinding::new_from_gpui( - // gpui::KeyBinding::new("ctrl-k ctrl-b", gpui::NoAction, None), - // cx, - // ) - // .into_any_element(), - // ), - // single_example( - // "With Shift", - // KeyBinding::new_from_gpui( - // gpui::KeyBinding::new("shift-cmd-p", gpui::NoAction, None), - // cx, - // ) - // .into_any_element(), - // ), - // ], - // ), - // ]) - // .into_any_element(), - // ) - // } + v_flex() + .gap_6() + .children(vec![example_group_with_title( + "Platform Styles", + vec![ + single_example( + "Mac Style", + keybinding("cmd-s") + .platform_style(PlatformStyle::Mac) + .into_any_element(), + ), + single_example( + "Linux Style", + keybinding("ctrl-s") + .platform_style(PlatformStyle::Linux) + .into_any_element(), + ), + single_example( + "Windows Style", + keybinding("ctrl-s") + .platform_style(PlatformStyle::Windows) + .into_any_element(), + ), + ], + )]) + .into_any_element() + } } #[cfg(test)] diff --git a/crates/ui/src/components/keybinding_hint.rs b/crates/ui/src/components/keybinding_hint.rs index 9da470c4ee4173..86a355418a6565 100644 --- a/crates/ui/src/components/keybinding_hint.rs +++ b/crates/ui/src/components/keybinding_hint.rs @@ -259,74 +259,68 @@ impl Component for KeybindingHint { ComponentScope::DataDisplay } - fn description() -> Option<&'static str> { - Some("Displays a keyboard shortcut hint with optional prefix and suffix text") + fn description() -> &'static str { + "Displays a keyboard shortcut hint with optional prefix and suffix text" } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let enter = KeyBinding::for_action(&menu::Confirm, cx); let bg_color = cx.theme().colors().surface_background; - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Basic", - vec![ - single_example( - "With Prefix", - KeybindingHint::with_prefix( - "Go to Start:", - enter.clone(), - bg_color, - ) + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Basic", + vec![ + single_example( + "With Prefix", + KeybindingHint::with_prefix("Go to Start:", enter.clone(), bg_color) .into_any_element(), - ), - single_example( - "With Suffix", - KeybindingHint::with_suffix(enter.clone(), "Go to End", bg_color) - .into_any_element(), - ), - single_example( - "With Prefix and Suffix", - KeybindingHint::new(enter.clone(), bg_color) - .prefix("Confirm:") - .suffix("Execute selected action") - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Sizes", - vec![ - single_example( - "Small", - KeybindingHint::new(enter.clone(), bg_color) - .size(Pixels::from(12.0)) - .prefix("Small:") - .into_any_element(), - ), - single_example( - "Medium", - KeybindingHint::new(enter.clone(), bg_color) - .size(Pixels::from(16.0)) - .suffix("Medium") - .into_any_element(), - ), - single_example( - "Large", - KeybindingHint::new(enter, bg_color) - .size(Pixels::from(20.0)) - .prefix("Large:") - .suffix("Size") - .into_any_element(), - ), - ], - ), - ]) - .into_any_element(), - ) + ), + single_example( + "With Suffix", + KeybindingHint::with_suffix(enter.clone(), "Go to End", bg_color) + .into_any_element(), + ), + single_example( + "With Prefix and Suffix", + KeybindingHint::new(enter.clone(), bg_color) + .prefix("Confirm:") + .suffix("Execute selected action") + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Sizes", + vec![ + single_example( + "Small", + KeybindingHint::new(enter.clone(), bg_color) + .size(Pixels::from(12.0)) + .prefix("Small:") + .into_any_element(), + ), + single_example( + "Medium", + KeybindingHint::new(enter.clone(), bg_color) + .size(Pixels::from(16.0)) + .suffix("Medium") + .into_any_element(), + ), + single_example( + "Large", + KeybindingHint::new(enter, bg_color) + .size(Pixels::from(20.0)) + .prefix("Large:") + .suffix("Size") + .into_any_element(), + ), + ], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/label/highlighted_label.rs b/crates/ui/src/components/label/highlighted_label.rs index 6d5b1d5645a68c..b3f19e0060404c 100644 --- a/crates/ui/src/components/label/highlighted_label.rs +++ b/crates/ui/src/components/label/highlighted_label.rs @@ -223,89 +223,94 @@ impl Component for HighlightedLabel { "HighlightedLabel" } - fn description() -> Option<&'static str> { - Some("A label with highlighted characters based on specified indices.") + fn description() -> &'static str { + "A label with highlighted characters based on specified indices." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Basic Usage", - vec![ - single_example( - "Default", - HighlightedLabel::new("Highlighted Text", vec![0, 1, 2, 3]).into_any_element(), - ), - single_example( - "Custom Color", - HighlightedLabel::new("Colored Highlight", vec![0, 1, 7, 8, 9]) - .color(Color::Accent) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Styles", - vec![ - single_example( - "Bold", - HighlightedLabel::new("Bold Highlight", vec![0, 1, 2, 3]) - .weight(FontWeight::BOLD) - .into_any_element(), - ), - single_example( - "Italic", - HighlightedLabel::new("Italic Highlight", vec![0, 1, 6, 7, 8]) - .italic() - .into_any_element(), - ), - single_example( - "Underline", - HighlightedLabel::new("Underlined Highlight", vec![0, 1, 10, 11, 12]) - .underline() - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Sizes", - vec![ - single_example( - "Small", - HighlightedLabel::new("Small Highlight", vec![0, 1, 5, 6, 7]) - .size(LabelSize::Small) - .into_any_element(), - ), - single_example( - "Large", - HighlightedLabel::new("Large Highlight", vec![0, 1, 5, 6, 7]) - .size(LabelSize::Large) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Special Cases", - vec![ - single_example( - "Single Line", - HighlightedLabel::new("Single Line Highlight\nWith Newline", vec![0, 1, 7, 8, 9]) - .single_line() - .into_any_element(), - ), - single_example( - "Truncate", - HighlightedLabel::new("This is a very long text that should be truncated with highlights", vec![0, 1, 2, 3, 4, 5]) - .truncate() - .into_any_element(), - ), - ], - ), - ]) - .into_any_element() - ) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Basic Usage", + vec![ + single_example( + "Default", + HighlightedLabel::new("Highlighted Text", vec![0, 1, 2, 3]) + .into_any_element(), + ), + single_example( + "Custom Color", + HighlightedLabel::new("Colored Highlight", vec![0, 1, 7, 8, 9]) + .color(Color::Accent) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Styles", + vec![ + single_example( + "Bold", + HighlightedLabel::new("Bold Highlight", vec![0, 1, 2, 3]) + .weight(FontWeight::BOLD) + .into_any_element(), + ), + single_example( + "Italic", + HighlightedLabel::new("Italic Highlight", vec![0, 1, 6, 7, 8]) + .italic() + .into_any_element(), + ), + single_example( + "Underline", + HighlightedLabel::new("Underlined Highlight", vec![0, 1, 10, 11, 12]) + .underline() + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Sizes", + vec![ + single_example( + "Small", + HighlightedLabel::new("Small Highlight", vec![0, 1, 5, 6, 7]) + .size(LabelSize::Small) + .into_any_element(), + ), + single_example( + "Large", + HighlightedLabel::new("Large Highlight", vec![0, 1, 5, 6, 7]) + .size(LabelSize::Large) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Special Cases", + vec![ + single_example( + "Single Line", + HighlightedLabel::new( + "Single Line Highlight\nWith Newline", + vec![0, 1, 7, 8, 9], + ) + .single_line() + .into_any_element(), + ), + single_example( + "Truncate", + HighlightedLabel::new( + "This is a very long text that should be truncated with highlights", + vec![0, 1, 2, 3, 4, 5], + ) + .truncate() + .into_any_element(), + ), + ], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/label/label.rs b/crates/ui/src/components/label/label.rs index 871f53fbe4d008..370c9166c36cb9 100644 --- a/crates/ui/src/components/label/label.rs +++ b/crates/ui/src/components/label/label.rs @@ -352,13 +352,13 @@ impl Component for Label { ComponentScope::Typography } - fn description() -> Option<&'static str> { - Some("A text label component that supports various styles, sizes, and formatting options.") + fn description() -> &'static str { + "A text label component that supports various styles, \ + sizes, and formatting options." } - fn preview(_window: &mut Window, cx: &mut App) -> Option { - Some( - v_flex() + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { + v_flex() .gap_6() .children(vec![ example_group_with_title( @@ -405,6 +405,5 @@ impl Component for Label { ), ]) .into_any_element() - ) } } diff --git a/crates/ui/src/components/label/label_like.rs b/crates/ui/src/components/label/label_like.rs index 5cad04efcfabcc..27eb9e797fac65 100644 --- a/crates/ui/src/components/label/label_like.rs +++ b/crates/ui/src/components/label/label_like.rs @@ -271,15 +271,13 @@ impl Component for LabelLike { "LabelLike" } - fn description() -> Option<&'static str> { - Some( - "A flexible, customizable label-like component that serves as a base for other label types.", - ) + fn description() -> &'static str { + "A flexible, customizable label-like component \ + that serves as a base for other label types." } - fn preview(_window: &mut Window, cx: &mut App) -> Option { - Some( - v_flex() + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { + v_flex() .gap_6() .children(vec![ example_group_with_title( @@ -326,6 +324,5 @@ impl Component for LabelLike { ), ]) .into_any_element() - ) } } diff --git a/crates/ui/src/components/label/spinner_label.rs b/crates/ui/src/components/label/spinner_label.rs index 33eeeae125106c..583debde9cbc5d 100644 --- a/crates/ui/src/components/label/spinner_label.rs +++ b/crates/ui/src/components/label/spinner_label.rs @@ -190,7 +190,12 @@ impl Component for SpinnerLabel { "Spinner Label" } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { + fn description() -> &'static str { + "A text-based loading indicator that animates through a sequence of \ + unicode glyphs to show ongoing or indeterminate work." + } + + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { let examples = vec![ single_example("Default", SpinnerLabel::new().into_any_element()), single_example( @@ -200,6 +205,6 @@ impl Component for SpinnerLabel { single_example("Sand Variant", SpinnerLabel::sand().into_any_element()), ]; - Some(example_group(examples).vertical().into_any_element()) + example_group(examples).vertical().into_any_element() } } diff --git a/crates/ui/src/components/list/list.rs b/crates/ui/src/components/list/list.rs index ccae5bed23d950..4659c7e16b5d6e 100644 --- a/crates/ui/src/components/list/list.rs +++ b/crates/ui/src/components/list/list.rs @@ -99,44 +99,41 @@ impl Component for List { ComponentScope::Layout } - fn description() -> Option<&'static str> { - Some( - "A container component for displaying a collection of list items with optional header and empty state.", - ) + fn description() -> &'static str { + "A container component for displaying a collection of list items \ + with optional header and empty state." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![example_group_with_title( - "Basic Lists", - vec![ - single_example( - "Simple List", - List::new() - .child(ListItem::new("item1").child(Label::new("Item 1"))) - .child(ListItem::new("item2").child(Label::new("Item 2"))) - .child(ListItem::new("item3").child(Label::new("Item 3"))) - .into_any_element(), - ), - single_example( - "With Header", - List::new() - .header(ListHeader::new("Section Header")) - .child(ListItem::new("item1").child(Label::new("Item 1"))) - .child(ListItem::new("item2").child(Label::new("Item 2"))) - .into_any_element(), - ), - single_example( - "Empty List", - List::new() - .empty_message("No items to display") - .into_any_element(), - ), - ], - )]) - .into_any_element(), - ) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![example_group_with_title( + "Basic Lists", + vec![ + single_example( + "Simple List", + List::new() + .child(ListItem::new("item1").child(Label::new("Item 1"))) + .child(ListItem::new("item2").child(Label::new("Item 2"))) + .child(ListItem::new("item3").child(Label::new("Item 3"))) + .into_any_element(), + ), + single_example( + "With Header", + List::new() + .header(ListHeader::new("Section Header")) + .child(ListItem::new("item1").child(Label::new("Item 1"))) + .child(ListItem::new("item2").child(Label::new("Item 2"))) + .into_any_element(), + ), + single_example( + "Empty List", + List::new() + .empty_message("No items to display") + .into_any_element(), + ), + ], + )]) + .into_any_element() } } diff --git a/crates/ui/src/components/list/list_bullet_item.rs b/crates/ui/src/components/list/list_bullet_item.rs index 934f0853dbe18b..8fed3158756e73 100644 --- a/crates/ui/src/components/list/list_bullet_item.rs +++ b/crates/ui/src/components/list/list_bullet_item.rs @@ -71,11 +71,11 @@ impl Component for ListBulletItem { ComponentScope::DataDisplay } - fn description() -> Option<&'static str> { - Some("A list item with a dash indicator for unordered lists.") + fn description() -> &'static str { + "A list item with a dash indicator for unordered lists." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { let basic_examples = vec![ single_example( "Simple", @@ -105,11 +105,9 @@ impl Component for ListBulletItem { ), ]; - Some( - v_flex() - .gap_6() - .child(example_group(basic_examples).vertical()) - .into_any_element(), - ) + v_flex() + .gap_6() + .child(example_group(basic_examples).vertical()) + .into_any_element() } } diff --git a/crates/ui/src/components/list/list_header.rs b/crates/ui/src/components/list/list_header.rs index 9d72366c3be490..741f60ba34dbda 100644 --- a/crates/ui/src/components/list/list_header.rs +++ b/crates/ui/src/components/list/list_header.rs @@ -144,74 +144,71 @@ impl Component for ListHeader { ComponentScope::DataDisplay } - fn description() -> Option<&'static str> { - Some( - "A header component for lists with support for icons, actions, and collapsible sections.", - ) + fn description() -> &'static str { + "A header component for lists with support for icons, actions, \ + and collapsible sections." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Basic Headers", - vec![ - single_example( - "Simple", - ListHeader::new("Section Header").into_any_element(), - ), - single_example( - "With Icon", - ListHeader::new("Files") - .start_slot(Icon::new(IconName::File)) - .into_any_element(), - ), - single_example( - "With End Slot", - ListHeader::new("Recent") - .end_slot(Label::new("5").color(Color::Muted)) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Collapsible Headers", - vec![ - single_example( - "Expanded", - ListHeader::new("Expanded Section") - .toggle(Some(true)) - .into_any_element(), - ), - single_example( - "Collapsed", - ListHeader::new("Collapsed Section") - .toggle(Some(false)) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "States", - vec![ - single_example( - "Selected", - ListHeader::new("Selected Header") - .toggle_state(true) - .into_any_element(), - ), - single_example( - "Inset", - ListHeader::new("Inset Header") - .inset(true) - .into_any_element(), - ), - ], - ), - ]) - .into_any_element(), - ) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Basic Headers", + vec![ + single_example( + "Simple", + ListHeader::new("Section Header").into_any_element(), + ), + single_example( + "With Icon", + ListHeader::new("Files") + .start_slot(Icon::new(IconName::File)) + .into_any_element(), + ), + single_example( + "With End Slot", + ListHeader::new("Recent") + .end_slot(Label::new("5").color(Color::Muted)) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Collapsible Headers", + vec![ + single_example( + "Expanded", + ListHeader::new("Expanded Section") + .toggle(Some(true)) + .into_any_element(), + ), + single_example( + "Collapsed", + ListHeader::new("Collapsed Section") + .toggle(Some(false)) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "States", + vec![ + single_example( + "Selected", + ListHeader::new("Selected Header") + .toggle_state(true) + .into_any_element(), + ), + single_example( + "Inset", + ListHeader::new("Inset Header") + .inset(true) + .into_any_element(), + ), + ], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/list/list_item.rs b/crates/ui/src/components/list/list_item.rs index ece1fd3c61ec48..06be27abab2429 100644 --- a/crates/ui/src/components/list/list_item.rs +++ b/crates/ui/src/components/list/list_item.rs @@ -385,109 +385,106 @@ impl Component for ListItem { ComponentScope::DataDisplay } - fn description() -> Option<&'static str> { - Some( - "A flexible list item component with support for icons, actions, disclosure toggles, and hierarchical display.", - ) + fn description() -> &'static str { + "A flexible list item component with support for icons, actions, \ + disclosure toggles, and hierarchical display." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Basic List Items", - vec![ - single_example( - "Simple", - ListItem::new("simple") - .child(Label::new("Simple list item")) - .into_any_element(), - ), - single_example( - "With Icon", - ListItem::new("with_icon") - .start_slot(Icon::new(IconName::File)) - .child(Label::new("List item with icon")) - .into_any_element(), - ), - single_example( - "Selected", - ListItem::new("selected") - .toggle_state(true) - .start_slot(Icon::new(IconName::Check)) - .child(Label::new("Selected item")) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "List Item Spacing", - vec![ - single_example( - "Dense", - ListItem::new("dense") - .spacing(ListItemSpacing::Dense) - .child(Label::new("Dense spacing")) - .into_any_element(), - ), - single_example( - "Extra Dense", - ListItem::new("extra_dense") - .spacing(ListItemSpacing::ExtraDense) - .child(Label::new("Extra dense spacing")) - .into_any_element(), - ), - single_example( - "Sparse", - ListItem::new("sparse") - .spacing(ListItemSpacing::Sparse) - .child(Label::new("Sparse spacing")) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "With Slots", - vec![ - single_example( - "End Slot", - ListItem::new("end_slot") - .child(Label::new("Item with end slot")) - .end_slot(Icon::new(IconName::ChevronRight)) - .into_any_element(), - ), - single_example( - "With Toggle", - ListItem::new("with_toggle") - .toggle(Some(true)) - .child(Label::new("Expandable item")) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "States", - vec![ - single_example( - "Disabled", - ListItem::new("disabled") - .disabled(true) - .child(Label::new("Disabled item")) - .into_any_element(), - ), - single_example( - "Non-selectable", - ListItem::new("non_selectable") - .selectable(false) - .child(Label::new("Non-selectable item")) - .into_any_element(), - ), - ], - ), - ]) - .into_any_element(), - ) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Basic List Items", + vec![ + single_example( + "Simple", + ListItem::new("simple") + .child(Label::new("Simple list item")) + .into_any_element(), + ), + single_example( + "With Icon", + ListItem::new("with_icon") + .start_slot(Icon::new(IconName::File)) + .child(Label::new("List item with icon")) + .into_any_element(), + ), + single_example( + "Selected", + ListItem::new("selected") + .toggle_state(true) + .start_slot(Icon::new(IconName::Check)) + .child(Label::new("Selected item")) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "List Item Spacing", + vec![ + single_example( + "Dense", + ListItem::new("dense") + .spacing(ListItemSpacing::Dense) + .child(Label::new("Dense spacing")) + .into_any_element(), + ), + single_example( + "Extra Dense", + ListItem::new("extra_dense") + .spacing(ListItemSpacing::ExtraDense) + .child(Label::new("Extra dense spacing")) + .into_any_element(), + ), + single_example( + "Sparse", + ListItem::new("sparse") + .spacing(ListItemSpacing::Sparse) + .child(Label::new("Sparse spacing")) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "With Slots", + vec![ + single_example( + "End Slot", + ListItem::new("end_slot") + .child(Label::new("Item with end slot")) + .end_slot(Icon::new(IconName::ChevronRight)) + .into_any_element(), + ), + single_example( + "With Toggle", + ListItem::new("with_toggle") + .toggle(Some(true)) + .child(Label::new("Expandable item")) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "States", + vec![ + single_example( + "Disabled", + ListItem::new("disabled") + .disabled(true) + .child(Label::new("Disabled item")) + .into_any_element(), + ), + single_example( + "Non-selectable", + ListItem::new("non_selectable") + .selectable(false) + .child(Label::new("Non-selectable item")) + .into_any_element(), + ), + ], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/list/list_sub_header.rs b/crates/ui/src/components/list/list_sub_header.rs index b4a82fb2edf5fc..6c0f8df3aa11ea 100644 --- a/crates/ui/src/components/list/list_sub_header.rs +++ b/crates/ui/src/components/list/list_sub_header.rs @@ -91,59 +91,54 @@ impl Component for ListSubHeader { ComponentScope::DataDisplay } - fn description() -> Option<&'static str> { - Some( - "A sub-header component for organizing list content into subsections with optional icons and end slots.", - ) + fn description() -> &'static str { + "A sub-header component for organizing list content into subsections \ + with optional icons and end slots." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Basic Sub-headers", - vec![ - single_example( - "Simple", - ListSubHeader::new("Subsection").into_any_element(), - ), - single_example( - "With Icon", - ListSubHeader::new("Documents") - .left_icon(Some(IconName::File)) - .into_any_element(), - ), - single_example( - "With End Slot", - ListSubHeader::new("Recent") - .end_slot( - Label::new("3").color(Color::Muted).into_any_element(), - ) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "States", - vec![ - single_example( - "Selected", - ListSubHeader::new("Selected") - .toggle_state(true) - .into_any_element(), - ), - single_example( - "Inset", - ListSubHeader::new("Inset Sub-header") - .inset(true) - .into_any_element(), - ), - ], - ), - ]) - .into_any_element(), - ) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Basic Sub-headers", + vec![ + single_example( + "Simple", + ListSubHeader::new("Subsection").into_any_element(), + ), + single_example( + "With Icon", + ListSubHeader::new("Documents") + .left_icon(Some(IconName::File)) + .into_any_element(), + ), + single_example( + "With End Slot", + ListSubHeader::new("Recent") + .end_slot(Label::new("3").color(Color::Muted).into_any_element()) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "States", + vec![ + single_example( + "Selected", + ListSubHeader::new("Selected") + .toggle_state(true) + .into_any_element(), + ), + single_example( + "Inset", + ListSubHeader::new("Inset Sub-header") + .inset(true) + .into_any_element(), + ), + ], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/notification/alert_modal.rs b/crates/ui/src/components/notification/alert_modal.rs index 52a084c847887a..5c368a9a7457da 100644 --- a/crates/ui/src/components/notification/alert_modal.rs +++ b/crates/ui/src/components/notification/alert_modal.rs @@ -174,13 +174,12 @@ impl Component for AlertModal { ComponentStatus::WorkInProgress } - fn description() -> Option<&'static str> { - Some("A modal dialog that presents an alert message with primary and dismiss actions.") + fn description() -> &'static str { + "A modal dialog that presents an alert message with primary and dismiss actions." } - fn preview(_window: &mut Window, cx: &mut App) -> Option { - Some( - v_flex() + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { + v_flex() .gap_6() .p_4() .children(vec![ @@ -246,7 +245,6 @@ Review .zed/settings.json for any extensions or commands configured by this proj .into_any_element(), )]), ]) - .into_any_element(), - ) + .into_any_element() } } diff --git a/crates/ui/src/components/notification/announcement_toast.rs b/crates/ui/src/components/notification/announcement_toast.rs index 215d8b9aedfa45..d47d264843c913 100644 --- a/crates/ui/src/components/notification/announcement_toast.rs +++ b/crates/ui/src/components/notification/announcement_toast.rs @@ -160,11 +160,11 @@ impl Component for AnnouncementToast { ComponentScope::Notification } - fn description() -> Option<&'static str> { - Some("A special toast for announcing new and exciting features.") + fn description() -> &'static str { + "A special toast for announcing new and exciting features." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { let examples = vec![single_example( "Basic", div() @@ -188,11 +188,9 @@ impl Component for AnnouncementToast { .into_any_element(), )]; - Some( - v_flex() - .gap_6() - .child(example_group(examples).vertical()) - .into_any_element(), - ) + v_flex() + .gap_6() + .child(example_group(examples).vertical()) + .into_any_element() } } diff --git a/crates/ui/src/components/progress/circular_progress.rs b/crates/ui/src/components/progress/circular_progress.rs index f571332edaec73..69f93b740cd86e 100644 --- a/crates/ui/src/components/progress/circular_progress.rs +++ b/crates/ui/src/components/progress/circular_progress.rs @@ -175,49 +175,46 @@ impl Component for CircularProgress { ComponentScope::Status } - fn description() -> Option<&'static str> { - Some( - "A circular progress indicator that displays progress as an arc growing clockwise from the top.", - ) + fn description() -> &'static str { + "A circular progress indicator that displays progress as an arc \ + growing clockwise from the top." } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let max_value = 100.0; let container = || v_flex().items_center().gap_1(); - Some( - example_group(vec![single_example( - "Examples", - h_flex() - .gap_6() - .child( - container() - .child(CircularProgress::new(0.0, max_value, px(48.0), cx)) - .child(Label::new("0%").size(LabelSize::Small)), - ) - .child( - container() - .child(CircularProgress::new(25.0, max_value, px(48.0), cx)) - .child(Label::new("25%").size(LabelSize::Small)), - ) - .child( - container() - .child(CircularProgress::new(50.0, max_value, px(48.0), cx)) - .child(Label::new("50%").size(LabelSize::Small)), - ) - .child( - container() - .child(CircularProgress::new(75.0, max_value, px(48.0), cx)) - .child(Label::new("75%").size(LabelSize::Small)), - ) - .child( - container() - .child(CircularProgress::new(100.0, max_value, px(48.0), cx)) - .child(Label::new("100%").size(LabelSize::Small)), - ) - .into_any_element(), - )]) - .into_any_element(), - ) + example_group(vec![single_example( + "Examples", + h_flex() + .gap_6() + .child( + container() + .child(CircularProgress::new(0.0, max_value, px(48.0), cx)) + .child(Label::new("0%").size(LabelSize::Small)), + ) + .child( + container() + .child(CircularProgress::new(25.0, max_value, px(48.0), cx)) + .child(Label::new("25%").size(LabelSize::Small)), + ) + .child( + container() + .child(CircularProgress::new(50.0, max_value, px(48.0), cx)) + .child(Label::new("50%").size(LabelSize::Small)), + ) + .child( + container() + .child(CircularProgress::new(75.0, max_value, px(48.0), cx)) + .child(Label::new("75%").size(LabelSize::Small)), + ) + .child( + container() + .child(CircularProgress::new(100.0, max_value, px(48.0), cx)) + .child(Label::new("100%").size(LabelSize::Small)), + ) + .into_any_element(), + )]) + .into_any_element() } } diff --git a/crates/ui/src/components/progress/progress_bar.rs b/crates/ui/src/components/progress/progress_bar.rs index b46b0523681e84..5f79eab4e7cae4 100644 --- a/crates/ui/src/components/progress/progress_bar.rs +++ b/crates/ui/src/components/progress/progress_bar.rs @@ -93,53 +93,51 @@ impl Component for ProgressBar { ComponentScope::Status } - fn description() -> Option<&'static str> { - Some(Self::DOCS) + fn description() -> &'static str { + Self::DOCS } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let max_value = 180.0; let container = || v_flex().w_full().gap_1(); - Some( - example_group(vec![single_example( - "Examples", - v_flex() - .w_full() - .gap_2() - .child( - container() - .child( - h_flex() - .justify_between() - .child(Label::new("0%")) - .child(Label::new("Empty")), - ) - .child(ProgressBar::new("empty", 0.0, max_value, cx)), - ) - .child( - container() - .child( - h_flex() - .justify_between() - .child(Label::new("38%")) - .child(Label::new("Partial")), - ) - .child(ProgressBar::new("partial", max_value * 0.35, max_value, cx)), - ) - .child( - container() - .child( - h_flex() - .justify_between() - .child(Label::new("100%")) - .child(Label::new("Complete")), - ) - .child(ProgressBar::new("filled", max_value, max_value, cx)), - ) - .into_any_element(), - )]) - .into_any_element(), - ) + example_group(vec![single_example( + "Examples", + v_flex() + .w_full() + .gap_2() + .child( + container() + .child( + h_flex() + .justify_between() + .child(Label::new("0%")) + .child(Label::new("Empty")), + ) + .child(ProgressBar::new("empty", 0.0, max_value, cx)), + ) + .child( + container() + .child( + h_flex() + .justify_between() + .child(Label::new("38%")) + .child(Label::new("Partial")), + ) + .child(ProgressBar::new("partial", max_value * 0.35, max_value, cx)), + ) + .child( + container() + .child( + h_flex() + .justify_between() + .child(Label::new("100%")) + .child(Label::new("Complete")), + ) + .child(ProgressBar::new("filled", max_value, max_value, cx)), + ) + .into_any_element(), + )]) + .into_any_element() } } diff --git a/crates/ui/src/components/tab.rs b/crates/ui/src/components/tab.rs index e6823f46b75048..6a25ad4345752c 100644 --- a/crates/ui/src/components/tab.rs +++ b/crates/ui/src/components/tab.rs @@ -185,54 +185,51 @@ impl Component for Tab { ComponentScope::Navigation } - fn description() -> Option<&'static str> { - Some( - "A tab component that can be used in a tabbed interface, supporting different positions and states.", - ) + fn description() -> &'static str { + "A tab component that can be used in a tabbed interface, \ + supporting different positions and states." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![example_group_with_title( - "Variations", - vec![ - single_example( - "Default", - Tab::new("default").child("Default Tab").into_any_element(), - ), - single_example( - "Selected", - Tab::new("selected") - .toggle_state(true) - .child("Selected Tab") - .into_any_element(), - ), - single_example( - "First", - Tab::new("first") - .position(TabPosition::First) - .child("First Tab") - .into_any_element(), - ), - single_example( - "Middle", - Tab::new("middle") - .position(TabPosition::Middle(Ordering::Equal)) - .child("Middle Tab") - .into_any_element(), - ), - single_example( - "Last", - Tab::new("last") - .position(TabPosition::Last) - .child("Last Tab") - .into_any_element(), - ), - ], - )]) - .into_any_element(), - ) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![example_group_with_title( + "Variations", + vec![ + single_example( + "Default", + Tab::new("default").child("Default Tab").into_any_element(), + ), + single_example( + "Selected", + Tab::new("selected") + .toggle_state(true) + .child("Selected Tab") + .into_any_element(), + ), + single_example( + "First", + Tab::new("first") + .position(TabPosition::First) + .child("First Tab") + .into_any_element(), + ), + single_example( + "Middle", + Tab::new("middle") + .position(TabPosition::Middle(Ordering::Equal)) + .child("Middle Tab") + .into_any_element(), + ), + single_example( + "Last", + Tab::new("last") + .position(TabPosition::Last) + .child("Last Tab") + .into_any_element(), + ), + ], + )]) + .into_any_element() } } diff --git a/crates/ui/src/components/tab_bar.rs b/crates/ui/src/components/tab_bar.rs index 7ebbaab0719c6e..0891b3ac1f4949 100644 --- a/crates/ui/src/components/tab_bar.rs +++ b/crates/ui/src/components/tab_bar.rs @@ -161,47 +161,46 @@ impl Component for TabBar { "TabBar" } - fn description() -> Option<&'static str> { - Some("A horizontal bar containing tabs for navigation between different views or sections.") + fn description() -> &'static str { + "A horizontal bar containing tabs for navigation between different views \ + or sections." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Basic Usage", - vec![ - single_example( - "Empty TabBar", - TabBar::new("empty_tab_bar").into_any_element(), - ), - single_example( - "With Tabs", - TabBar::new("tab_bar_with_tabs") - .child(Tab::new("tab1")) - .child(Tab::new("tab2")) - .child(Tab::new("tab3")) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "With Start and End Children", - vec![single_example( - "Full TabBar", - TabBar::new("full_tab_bar") - .start_child(Button::new("start_button", "Start")) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Basic Usage", + vec![ + single_example( + "Empty TabBar", + TabBar::new("empty_tab_bar").into_any_element(), + ), + single_example( + "With Tabs", + TabBar::new("tab_bar_with_tabs") .child(Tab::new("tab1")) .child(Tab::new("tab2")) .child(Tab::new("tab3")) - .end_child(Button::new("end_button", "End")) .into_any_element(), - )], - ), - ]) - .into_any_element(), - ) + ), + ], + ), + example_group_with_title( + "With Start and End Children", + vec![single_example( + "Full TabBar", + TabBar::new("full_tab_bar") + .start_child(Button::new("start_button", "Start")) + .child(Tab::new("tab1")) + .child(Tab::new("tab2")) + .child(Tab::new("tab3")) + .end_child(Button::new("end_button", "End")) + .into_any_element(), + )], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/toggle.rs b/crates/ui/src/components/toggle.rs index 0b1d7884687b5a..85568dbb01b34c 100644 --- a/crates/ui/src/components/toggle.rs +++ b/crates/ui/src/components/toggle.rs @@ -696,131 +696,129 @@ impl Component for SwitchField { ComponentScope::Input } - fn description() -> Option<&'static str> { - Some("A field component that combines a label, description, and switch") + fn description() -> &'static str { + "A field component that combines a label, description, and switch" } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "States", - vec![ - single_example( - "Unselected", - SwitchField::new( - "switch_field_unselected", - Some("Enable notifications"), - Some("Receive notifications when new messages arrive.".into()), - ToggleState::Unselected, - |_, _, _| {}, - ) - .into_any_element(), - ), - single_example( - "Selected", - SwitchField::new( - "switch_field_selected", - Some("Enable notifications"), - Some("Receive notifications when new messages arrive.".into()), - ToggleState::Selected, - |_, _, _| {}, - ) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Colors", - vec![ - single_example( - "Default", - SwitchField::new( - "switch_field_default", - Some("Default color"), - Some("This uses the default switch color.".into()), - ToggleState::Selected, - |_, _, _| {}, - ) - .into_any_element(), - ), - single_example( - "Accent", - SwitchField::new( - "switch_field_accent", - Some("Accent color"), - Some("This uses the accent color scheme.".into()), - ToggleState::Selected, - |_, _, _| {}, - ) - .color(SwitchColor::Accent) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Disabled", - vec![single_example( - "Disabled", + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "States", + vec![ + single_example( + "Unselected", SwitchField::new( - "switch_field_disabled", - Some("Disabled field"), - Some("This field is disabled and cannot be toggled.".into()), + "switch_field_unselected", + Some("Enable notifications"), + Some("Receive notifications when new messages arrive.".into()), + ToggleState::Unselected, + |_, _, _| {}, + ) + .into_any_element(), + ), + single_example( + "Selected", + SwitchField::new( + "switch_field_selected", + Some("Enable notifications"), + Some("Receive notifications when new messages arrive.".into()), ToggleState::Selected, |_, _, _| {}, ) - .disabled(true) .into_any_element(), - )], - ), - example_group_with_title( + ), + ], + ), + example_group_with_title( + "Colors", + vec![ + single_example( + "Default", + SwitchField::new( + "switch_field_default", + Some("Default color"), + Some("This uses the default switch color.".into()), + ToggleState::Selected, + |_, _, _| {}, + ) + .into_any_element(), + ), + single_example( + "Accent", + SwitchField::new( + "switch_field_accent", + Some("Accent color"), + Some("This uses the accent color scheme.".into()), + ToggleState::Selected, + |_, _, _| {}, + ) + .color(SwitchColor::Accent) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Disabled", + vec![single_example( + "Disabled", + SwitchField::new( + "switch_field_disabled", + Some("Disabled field"), + Some("This field is disabled and cannot be toggled.".into()), + ToggleState::Selected, + |_, _, _| {}, + ) + .disabled(true) + .into_any_element(), + )], + ), + example_group_with_title( + "No Description", + vec![single_example( "No Description", - vec![single_example( - "No Description", + SwitchField::new( + "switch_field_disabled", + Some("Disabled field"), + None, + ToggleState::Selected, + |_, _, _| {}, + ) + .into_any_element(), + )], + ), + example_group_with_title( + "With Tooltip", + vec![ + single_example( + "Tooltip with Description", SwitchField::new( - "switch_field_disabled", - Some("Disabled field"), + "switch_field_tooltip_with_desc", + Some("Nice Feature"), + Some("Enable advanced configuration options.".into()), + ToggleState::Unselected, + |_, _, _| {}, + ) + .tooltip(Tooltip::text("This is content for this tooltip!")) + .into_any_element(), + ), + single_example( + "Tooltip without Description", + SwitchField::new( + "switch_field_tooltip_no_desc", + Some("Nice Feature"), None, ToggleState::Selected, |_, _, _| {}, ) + .tooltip(Tooltip::text("This is content for this tooltip!")) .into_any_element(), - )], - ), - example_group_with_title( - "With Tooltip", - vec![ - single_example( - "Tooltip with Description", - SwitchField::new( - "switch_field_tooltip_with_desc", - Some("Nice Feature"), - Some("Enable advanced configuration options.".into()), - ToggleState::Unselected, - |_, _, _| {}, - ) - .tooltip(Tooltip::text("This is content for this tooltip!")) - .into_any_element(), - ), - single_example( - "Tooltip without Description", - SwitchField::new( - "switch_field_tooltip_no_desc", - Some("Nice Feature"), - None, - ToggleState::Selected, - |_, _, _| {}, - ) - .tooltip(Tooltip::text("This is content for this tooltip!")) - .into_any_element(), - ), - ], - ), - ]) - .into_any_element(), - ) + ), + ], + ), + ]) + .into_any_element() } } @@ -829,112 +827,105 @@ impl Component for Checkbox { ComponentScope::Input } - fn description() -> Option<&'static str> { - Some("A checkbox component that can be used for multiple choice selections") + fn description() -> &'static str { + "A checkbox component that can be used for multiple choice selections" } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "States", - vec![ - single_example( - "Unselected", - Checkbox::new("checkbox_unselected", ToggleState::Unselected) - .into_any_element(), - ), - single_example( - "Placeholder", - Checkbox::new("checkbox_indeterminate", ToggleState::Selected) - .placeholder(true) - .into_any_element(), - ), - single_example( - "Indeterminate", - Checkbox::new("checkbox_indeterminate", ToggleState::Indeterminate) - .into_any_element(), - ), - single_example( - "Selected", - Checkbox::new("checkbox_selected", ToggleState::Selected) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Styles", - vec![ - single_example( - "Default", - Checkbox::new("checkbox_default", ToggleState::Selected) - .into_any_element(), - ), - single_example( - "Filled", - Checkbox::new("checkbox_filled", ToggleState::Selected) - .fill() - .into_any_element(), - ), - single_example( - "ElevationBased", - Checkbox::new("checkbox_elevation", ToggleState::Selected) - .style(ToggleStyle::ElevationBased( - ElevationIndex::EditorSurface, - )) - .into_any_element(), - ), - single_example( - "Custom Color", - Checkbox::new("checkbox_custom", ToggleState::Selected) - .style(ToggleStyle::Custom(hsla(142.0 / 360., 0.68, 0.45, 0.7))) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Disabled", - vec![ - single_example( - "Unselected", - Checkbox::new( - "checkbox_disabled_unselected", - ToggleState::Unselected, - ) - .disabled(true) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "States", + vec![ + single_example( + "Unselected", + Checkbox::new("checkbox_unselected", ToggleState::Unselected) .into_any_element(), - ), - single_example( - "Selected", - Checkbox::new("checkbox_disabled_selected", ToggleState::Selected) - .disabled(true) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "With Label", - vec![single_example( + ), + single_example( + "Placeholder", + Checkbox::new("checkbox_indeterminate", ToggleState::Selected) + .placeholder(true) + .into_any_element(), + ), + single_example( + "Indeterminate", + Checkbox::new("checkbox_indeterminate", ToggleState::Indeterminate) + .into_any_element(), + ), + single_example( + "Selected", + Checkbox::new("checkbox_selected", ToggleState::Selected) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Styles", + vec![ + single_example( "Default", - Checkbox::new("checkbox_with_label", ToggleState::Selected) - .label("Always save on quit") + Checkbox::new("checkbox_default", ToggleState::Selected) .into_any_element(), - )], - ), - example_group_with_title( - "Extra", - vec![single_example( - "Visualization-Only", - Checkbox::new("viz_only", ToggleState::Selected) - .visualization_only(true) + ), + single_example( + "Filled", + Checkbox::new("checkbox_filled", ToggleState::Selected) + .fill() .into_any_element(), - )], - ), - ]) - .into_any_element(), - ) + ), + single_example( + "ElevationBased", + Checkbox::new("checkbox_elevation", ToggleState::Selected) + .style(ToggleStyle::ElevationBased(ElevationIndex::EditorSurface)) + .into_any_element(), + ), + single_example( + "Custom Color", + Checkbox::new("checkbox_custom", ToggleState::Selected) + .style(ToggleStyle::Custom(hsla(142.0 / 360., 0.68, 0.45, 0.7))) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Disabled", + vec![ + single_example( + "Unselected", + Checkbox::new("checkbox_disabled_unselected", ToggleState::Unselected) + .disabled(true) + .into_any_element(), + ), + single_example( + "Selected", + Checkbox::new("checkbox_disabled_selected", ToggleState::Selected) + .disabled(true) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "With Label", + vec![single_example( + "Default", + Checkbox::new("checkbox_with_label", ToggleState::Selected) + .label("Always save on quit") + .into_any_element(), + )], + ), + example_group_with_title( + "Extra", + vec![single_example( + "Visualization-Only", + Checkbox::new("viz_only", ToggleState::Selected) + .visualization_only(true) + .into_any_element(), + )], + ), + ]) + .into_any_element() } } @@ -943,120 +934,115 @@ impl Component for Switch { ComponentScope::Input } - fn description() -> Option<&'static str> { - Some("A switch component that represents binary states like on/off") + fn description() -> &'static str { + "A switch component that represents binary states like on/off" } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "States", - vec![ - single_example( - "Off", - Switch::new("switch_off", ToggleState::Unselected) - .on_click(|_, _, _cx| {}) - .into_any_element(), - ), - single_example( - "On", - Switch::new("switch_on", ToggleState::Selected) - .on_click(|_, _, _cx| {}) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Colors", - vec![ - single_example( - "Accent (Default)", - Switch::new("switch_accent_style", ToggleState::Selected) - .on_click(|_, _, _cx| {}) - .into_any_element(), - ), - single_example( - "Custom", - Switch::new("switch_custom_style", ToggleState::Selected) - .color(SwitchColor::Custom(hsla(300.0 / 360.0, 0.6, 0.6, 1.0))) - .on_click(|_, _, _cx| {}) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "Disabled", - vec![ - single_example( - "Off", - Switch::new("switch_disabled_off", ToggleState::Unselected) - .disabled(true) - .into_any_element(), - ), - single_example( - "On", - Switch::new("switch_disabled_on", ToggleState::Selected) - .disabled(true) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "With Label", - vec![ - single_example( - "Start Label", - Switch::new("switch_with_label_start", ToggleState::Selected) - .label("Always save on quit") - .label_position(SwitchLabelPosition::Start) - .into_any_element(), - ), - single_example( - "End Label", - Switch::new("switch_with_label_end", ToggleState::Selected) - .label("Always save on quit") - .label_position(SwitchLabelPosition::End) - .into_any_element(), - ), - single_example( - "Default Size Label", - Switch::new( - "switch_with_label_default_size", - ToggleState::Selected, - ) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "States", + vec![ + single_example( + "Off", + Switch::new("switch_off", ToggleState::Unselected) + .on_click(|_, _, _cx| {}) + .into_any_element(), + ), + single_example( + "On", + Switch::new("switch_on", ToggleState::Selected) + .on_click(|_, _, _cx| {}) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Colors", + vec![ + single_example( + "Accent (Default)", + Switch::new("switch_accent_style", ToggleState::Selected) + .on_click(|_, _, _cx| {}) + .into_any_element(), + ), + single_example( + "Custom", + Switch::new("switch_custom_style", ToggleState::Selected) + .color(SwitchColor::Custom(hsla(300.0 / 360.0, 0.6, 0.6, 1.0))) + .on_click(|_, _, _cx| {}) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Disabled", + vec![ + single_example( + "Off", + Switch::new("switch_disabled_off", ToggleState::Unselected) + .disabled(true) + .into_any_element(), + ), + single_example( + "On", + Switch::new("switch_disabled_on", ToggleState::Selected) + .disabled(true) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "With Label", + vec![ + single_example( + "Start Label", + Switch::new("switch_with_label_start", ToggleState::Selected) + .label("Always save on quit") + .label_position(SwitchLabelPosition::Start) + .into_any_element(), + ), + single_example( + "End Label", + Switch::new("switch_with_label_end", ToggleState::Selected) + .label("Always save on quit") + .label_position(SwitchLabelPosition::End) + .into_any_element(), + ), + single_example( + "Default Size Label", + Switch::new("switch_with_label_default_size", ToggleState::Selected) .label("Always save on quit") .label_size(LabelSize::Default) .into_any_element(), - ), - single_example( - "Small Size Label", - Switch::new("switch_with_label_small_size", ToggleState::Selected) - .label("Always save on quit") - .label_size(LabelSize::Small) - .into_any_element(), - ), - ], - ), - example_group_with_title( - "With Keybinding", - vec![single_example( - "Keybinding", - Switch::new("switch_with_keybinding", ToggleState::Selected) - .key_binding(Some(KeyBinding::from_keystrokes( - vec![KeybindingKeystroke::from_keystroke( - Keystroke::parse("cmd-s").unwrap(), - )] - .into(), - false, - ))) + ), + single_example( + "Small Size Label", + Switch::new("switch_with_label_small_size", ToggleState::Selected) + .label("Always save on quit") + .label_size(LabelSize::Small) .into_any_element(), - )], - ), - ]) - .into_any_element(), - ) + ), + ], + ), + example_group_with_title( + "With Keybinding", + vec![single_example( + "Keybinding", + Switch::new("switch_with_keybinding", ToggleState::Selected) + .key_binding(Some(KeyBinding::from_keystrokes( + vec![KeybindingKeystroke::from_keystroke( + Keystroke::parse("cmd-s").unwrap(), + )] + .into(), + false, + ))) + .into_any_element(), + )], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/components/tooltip.rs b/crates/ui/src/components/tooltip.rs index 8124b4ecbafdc6..82e7d9b1118f34 100644 --- a/crates/ui/src/components/tooltip.rs +++ b/crates/ui/src/components/tooltip.rs @@ -274,21 +274,18 @@ impl Component for Tooltip { ComponentScope::DataDisplay } - fn description() -> Option<&'static str> { - Some( - "A tooltip that appears when hovering over an element, optionally showing a keybinding or additional metadata.", - ) + fn description() -> &'static str { + "A tooltip that appears when hovering over an element, \ + optionally showing a keybinding or additional metadata." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - example_group(vec![single_example( - "Text only", - Button::new("delete-example", "Delete") - .tooltip(Tooltip::text("This is a tooltip!")) - .into_any_element(), - )]) - .into_any_element(), - ) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + example_group(vec![single_example( + "Text only", + Button::new("delete-example", "Delete") + .tooltip(Tooltip::text("This is a tooltip!")) + .into_any_element(), + )]) + .into_any_element() } } diff --git a/crates/ui/src/components/tree_view_item.rs b/crates/ui/src/components/tree_view_item.rs index f6d90fceff5bf9..9474548675dfa7 100644 --- a/crates/ui/src/components/tree_view_item.rs +++ b/crates/ui/src/components/tree_view_item.rs @@ -223,13 +223,12 @@ impl Component for TreeViewItem { ComponentScope::Navigation } - fn description() -> Option<&'static str> { - Some( - "A hierarchical list of items that may have a parent-child relationship where children can be toggled into view by expanding or collapsing their parent item.", - ) + fn description() -> &'static str { + "A hierarchical list of items that may have a parent-child relationship \ + where children can be toggled into view by expanding or collapsing their parent item." } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let container = || { v_flex() .p_2() @@ -239,58 +238,56 @@ impl Component for TreeViewItem { .bg(cx.theme().colors().panel_background) }; - Some( - example_group(vec![ - single_example( - "Basic Tree View", - container() - .child( - TreeViewItem::new("index-1", "Tree Item Root #1") - .root_item(true) - .toggle_state(true), - ) - .child(TreeViewItem::new("index-2", "Tree Item #2")) - .child(TreeViewItem::new("index-3", "Tree Item #3")) - .child(TreeViewItem::new("index-4", "Tree Item Root #2").root_item(true)) - .child(TreeViewItem::new("index-5", "Tree Item #5")) - .child(TreeViewItem::new("index-6", "Tree Item #6")) - .into_any_element(), - ), - single_example( - "Active Child", - container() - .child(TreeViewItem::new("index-1", "Tree Item Root #1").root_item(true)) - .child(TreeViewItem::new("index-2", "Tree Item #2").toggle_state(true)) - .child(TreeViewItem::new("index-3", "Tree Item #3")) - .into_any_element(), - ), - single_example( - "Focused Parent", - container() - .child( - TreeViewItem::new("index-1", "Tree Item Root #1") - .root_item(true) - .focused(true) - .toggle_state(true), - ) - .child(TreeViewItem::new("index-2", "Tree Item #2")) - .child(TreeViewItem::new("index-3", "Tree Item #3")) - .into_any_element(), - ), - single_example( - "Focused Child", - container() - .child( - TreeViewItem::new("index-1", "Tree Item Root #1") - .root_item(true) - .toggle_state(true), - ) - .child(TreeViewItem::new("index-2", "Tree Item #2").focused(true)) - .child(TreeViewItem::new("index-3", "Tree Item #3")) - .into_any_element(), - ), - ]) - .into_any_element(), - ) + example_group(vec![ + single_example( + "Basic Tree View", + container() + .child( + TreeViewItem::new("index-1", "Tree Item Root #1") + .root_item(true) + .toggle_state(true), + ) + .child(TreeViewItem::new("index-2", "Tree Item #2")) + .child(TreeViewItem::new("index-3", "Tree Item #3")) + .child(TreeViewItem::new("index-4", "Tree Item Root #2").root_item(true)) + .child(TreeViewItem::new("index-5", "Tree Item #5")) + .child(TreeViewItem::new("index-6", "Tree Item #6")) + .into_any_element(), + ), + single_example( + "Active Child", + container() + .child(TreeViewItem::new("index-1", "Tree Item Root #1").root_item(true)) + .child(TreeViewItem::new("index-2", "Tree Item #2").toggle_state(true)) + .child(TreeViewItem::new("index-3", "Tree Item #3")) + .into_any_element(), + ), + single_example( + "Focused Parent", + container() + .child( + TreeViewItem::new("index-1", "Tree Item Root #1") + .root_item(true) + .focused(true) + .toggle_state(true), + ) + .child(TreeViewItem::new("index-2", "Tree Item #2")) + .child(TreeViewItem::new("index-3", "Tree Item #3")) + .into_any_element(), + ), + single_example( + "Focused Child", + container() + .child( + TreeViewItem::new("index-1", "Tree Item Root #1") + .root_item(true) + .toggle_state(true), + ) + .child(TreeViewItem::new("index-2", "Tree Item #2").focused(true)) + .child(TreeViewItem::new("index-3", "Tree Item #3")) + .into_any_element(), + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/styles/animation.rs b/crates/ui/src/styles/animation.rs index aa64fc1907b7be..ea08b74ca9ae17 100644 --- a/crates/ui/src/styles/animation.rs +++ b/crates/ui/src/styles/animation.rs @@ -107,11 +107,11 @@ impl Component for Animation { ComponentScope::Utilities } - fn description() -> Option<&'static str> { - Some("Demonstrates various animation patterns and transitions available in the UI system.") + fn description() -> &'static str { + "Demonstrates various animation patterns and transitions available in the UI system." } - fn preview(_window: &mut Window, cx: &mut App) -> Option { + fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { let container_size = 128.0; let element_size = 32.0; let offset = container_size / 2.0 - element_size / 2.0; @@ -126,152 +126,150 @@ impl Component for Animation { .rounded_sm() }; - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Animate In", - vec![ - single_example( - "From Bottom", - container() - .size(px(container_size)) - .child( - div() - .id("animate-in-from-bottom") - .absolute() - .size(px(element_size)) - .left(px(offset)) - .rounded_md() - .bg(gpui::red()) - .animate_in_from_bottom(false), - ) - .into_any_element(), - ), - single_example( - "From Top", - container() - .size(px(container_size)) - .child( - div() - .id("animate-in-from-top") - .absolute() - .size(px(element_size)) - .left(px(offset)) - .rounded_md() - .bg(gpui::blue()) - .animate_in_from_top(false), - ) - .into_any_element(), - ), - single_example( - "From Left", - container() - .size(px(container_size)) - .child( - div() - .id("animate-in-from-left") - .absolute() - .size(px(element_size)) - .top(px(offset)) - .rounded_md() - .bg(gpui::green()) - .animate_in_from_left(false), - ) - .into_any_element(), - ), - single_example( - "From Right", - container() - .size(px(container_size)) - .child( - div() - .id("animate-in-from-right") - .absolute() - .size(px(element_size)) - .top(px(offset)) - .rounded_md() - .bg(gpui::yellow()) - .animate_in_from_right(false), - ) - .into_any_element(), - ), - ], - ) - .grow(), - example_group_with_title( - "Fade and Animate In", - vec![ - single_example( - "From Bottom", - container() - .size(px(container_size)) - .child( - div() - .id("fade-animate-in-from-bottom") - .absolute() - .size(px(element_size)) - .left(px(offset)) - .rounded_md() - .bg(gpui::red()) - .animate_in_from_bottom(true), - ) - .into_any_element(), - ), - single_example( - "From Top", - container() - .size(px(container_size)) - .child( - div() - .id("fade-animate-in-from-top") - .absolute() - .size(px(element_size)) - .left(px(offset)) - .rounded_md() - .bg(gpui::blue()) - .animate_in_from_top(true), - ) - .into_any_element(), - ), - single_example( - "From Left", - container() - .size(px(container_size)) - .child( - div() - .id("fade-animate-in-from-left") - .absolute() - .size(px(element_size)) - .top(px(offset)) - .rounded_md() - .bg(gpui::green()) - .animate_in_from_left(true), - ) - .into_any_element(), - ), - single_example( - "From Right", - container() - .size(px(container_size)) - .child( - div() - .id("fade-animate-in-from-right") - .absolute() - .size(px(element_size)) - .top(px(offset)) - .rounded_md() - .bg(gpui::yellow()) - .animate_in_from_right(true), - ) - .into_any_element(), - ), - ], - ) - .grow(), - ]) - .into_any_element(), - ) + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Animate In", + vec![ + single_example( + "From Bottom", + container() + .size(px(container_size)) + .child( + div() + .id("animate-in-from-bottom") + .absolute() + .size(px(element_size)) + .left(px(offset)) + .rounded_md() + .bg(gpui::red()) + .animate_in_from_bottom(false), + ) + .into_any_element(), + ), + single_example( + "From Top", + container() + .size(px(container_size)) + .child( + div() + .id("animate-in-from-top") + .absolute() + .size(px(element_size)) + .left(px(offset)) + .rounded_md() + .bg(gpui::blue()) + .animate_in_from_top(false), + ) + .into_any_element(), + ), + single_example( + "From Left", + container() + .size(px(container_size)) + .child( + div() + .id("animate-in-from-left") + .absolute() + .size(px(element_size)) + .top(px(offset)) + .rounded_md() + .bg(gpui::green()) + .animate_in_from_left(false), + ) + .into_any_element(), + ), + single_example( + "From Right", + container() + .size(px(container_size)) + .child( + div() + .id("animate-in-from-right") + .absolute() + .size(px(element_size)) + .top(px(offset)) + .rounded_md() + .bg(gpui::yellow()) + .animate_in_from_right(false), + ) + .into_any_element(), + ), + ], + ) + .grow(), + example_group_with_title( + "Fade and Animate In", + vec![ + single_example( + "From Bottom", + container() + .size(px(container_size)) + .child( + div() + .id("fade-animate-in-from-bottom") + .absolute() + .size(px(element_size)) + .left(px(offset)) + .rounded_md() + .bg(gpui::red()) + .animate_in_from_bottom(true), + ) + .into_any_element(), + ), + single_example( + "From Top", + container() + .size(px(container_size)) + .child( + div() + .id("fade-animate-in-from-top") + .absolute() + .size(px(element_size)) + .left(px(offset)) + .rounded_md() + .bg(gpui::blue()) + .animate_in_from_top(true), + ) + .into_any_element(), + ), + single_example( + "From Left", + container() + .size(px(container_size)) + .child( + div() + .id("fade-animate-in-from-left") + .absolute() + .size(px(element_size)) + .top(px(offset)) + .rounded_md() + .bg(gpui::green()) + .animate_in_from_left(true), + ) + .into_any_element(), + ), + single_example( + "From Right", + container() + .size(px(container_size)) + .child( + div() + .id("fade-animate-in-from-right") + .absolute() + .size(px(element_size)) + .top(px(offset)) + .rounded_md() + .bg(gpui::yellow()) + .animate_in_from_right(true), + ) + .into_any_element(), + ), + ], + ) + .grow(), + ]) + .into_any_element() } } diff --git a/crates/ui/src/styles/color.rs b/crates/ui/src/styles/color.rs index 586b2ccc576fc6..b28e40bff09af7 100644 --- a/crates/ui/src/styles/color.rs +++ b/crates/ui/src/styles/color.rs @@ -129,116 +129,114 @@ impl Component for Color { ComponentScope::Utilities } - fn description() -> Option<&'static str> { - Some(Color::DOCS) + fn description() -> &'static str { + Color::DOCS } - fn preview(_window: &mut gpui::Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_6() - .children(vec![ - example_group_with_title( - "Text Colors", - vec![ - single_example( - "Default", - Label::new("Default text color") - .color(Color::Default) - .into_any_element(), - ) - .description(Color::Default.get_variant_docs()), - single_example( - "Muted", - Label::new("Muted text color") - .color(Color::Muted) - .into_any_element(), - ) - .description(Color::Muted.get_variant_docs()), - single_example( - "Accent", - Label::new("Accent text color") - .color(Color::Accent) - .into_any_element(), - ) - .description(Color::Accent.get_variant_docs()), - single_example( - "Disabled", - Label::new("Disabled text color") - .color(Color::Disabled) - .into_any_element(), - ) - .description(Color::Disabled.get_variant_docs()), - ], - ), - example_group_with_title( - "Status Colors", - vec![ - single_example( - "Success", - Label::new("Success status") - .color(Color::Success) - .into_any_element(), - ) - .description(Color::Success.get_variant_docs()), - single_example( - "Warning", - Label::new("Warning status") - .color(Color::Warning) - .into_any_element(), - ) - .description(Color::Warning.get_variant_docs()), - single_example( - "Error", - Label::new("Error status") - .color(Color::Error) - .into_any_element(), - ) - .description(Color::Error.get_variant_docs()), - single_example( - "Info", - Label::new("Info status") - .color(Color::Info) - .into_any_element(), - ) - .description(Color::Info.get_variant_docs()), - ], - ), - example_group_with_title( - "Version Control Colors", - vec![ - single_example( - "Created", - Label::new("Created item") - .color(Color::Created) - .into_any_element(), - ) - .description(Color::Created.get_variant_docs()), - single_example( - "Modified", - Label::new("Modified item") - .color(Color::Modified) - .into_any_element(), - ) - .description(Color::Modified.get_variant_docs()), - single_example( - "Deleted", - Label::new("Deleted item") - .color(Color::Deleted) - .into_any_element(), - ) - .description(Color::Deleted.get_variant_docs()), - single_example( - "Conflict", - Label::new("Conflict item") - .color(Color::Conflict) - .into_any_element(), - ) - .description(Color::Conflict.get_variant_docs()), - ], - ), - ]) - .into_any_element(), - ) + fn preview(_window: &mut gpui::Window, _cx: &mut App) -> gpui::AnyElement { + v_flex() + .gap_6() + .children(vec![ + example_group_with_title( + "Text Colors", + vec![ + single_example( + "Default", + Label::new("Default text color") + .color(Color::Default) + .into_any_element(), + ) + .description(Color::Default.get_variant_docs()), + single_example( + "Muted", + Label::new("Muted text color") + .color(Color::Muted) + .into_any_element(), + ) + .description(Color::Muted.get_variant_docs()), + single_example( + "Accent", + Label::new("Accent text color") + .color(Color::Accent) + .into_any_element(), + ) + .description(Color::Accent.get_variant_docs()), + single_example( + "Disabled", + Label::new("Disabled text color") + .color(Color::Disabled) + .into_any_element(), + ) + .description(Color::Disabled.get_variant_docs()), + ], + ), + example_group_with_title( + "Status Colors", + vec![ + single_example( + "Success", + Label::new("Success status") + .color(Color::Success) + .into_any_element(), + ) + .description(Color::Success.get_variant_docs()), + single_example( + "Warning", + Label::new("Warning status") + .color(Color::Warning) + .into_any_element(), + ) + .description(Color::Warning.get_variant_docs()), + single_example( + "Error", + Label::new("Error status") + .color(Color::Error) + .into_any_element(), + ) + .description(Color::Error.get_variant_docs()), + single_example( + "Info", + Label::new("Info status") + .color(Color::Info) + .into_any_element(), + ) + .description(Color::Info.get_variant_docs()), + ], + ), + example_group_with_title( + "Version Control Colors", + vec![ + single_example( + "Created", + Label::new("Created item") + .color(Color::Created) + .into_any_element(), + ) + .description(Color::Created.get_variant_docs()), + single_example( + "Modified", + Label::new("Modified item") + .color(Color::Modified) + .into_any_element(), + ) + .description(Color::Modified.get_variant_docs()), + single_example( + "Deleted", + Label::new("Deleted item") + .color(Color::Deleted) + .into_any_element(), + ) + .description(Color::Deleted.get_variant_docs()), + single_example( + "Conflict", + Label::new("Conflict item") + .color(Color::Conflict) + .into_any_element(), + ) + .description(Color::Conflict.get_variant_docs()), + ], + ), + ]) + .into_any_element() } } diff --git a/crates/ui/src/styles/typography.rs b/crates/ui/src/styles/typography.rs index 69790d3d3dae6b..9d384c3795706a 100644 --- a/crates/ui/src/styles/typography.rs +++ b/crates/ui/src/styles/typography.rs @@ -250,45 +250,43 @@ impl Component for Headline { ComponentScope::Typography } - fn description() -> Option<&'static str> { - Some("A headline element used to emphasize text and create visual hierarchy in the UI.") + fn description() -> &'static str { + "A headline element used to emphasize text and create visual hierarchy in the UI." } - fn preview(_window: &mut Window, _cx: &mut App) -> Option { - Some( - v_flex() - .gap_1() - .children(vec![ - single_example( - "XLarge", - Headline::new("XLarge Headline") - .size(HeadlineSize::XLarge) - .into_any_element(), - ), - single_example( - "Large", - Headline::new("Large Headline") - .size(HeadlineSize::Large) - .into_any_element(), - ), - single_example( - "Medium (Default)", - Headline::new("Medium Headline").into_any_element(), - ), - single_example( - "Small", - Headline::new("Small Headline") - .size(HeadlineSize::Small) - .into_any_element(), - ), - single_example( - "XSmall", - Headline::new("XSmall Headline") - .size(HeadlineSize::XSmall) - .into_any_element(), - ), - ]) - .into_any_element(), - ) + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + v_flex() + .gap_1() + .children(vec![ + single_example( + "XLarge", + Headline::new("XLarge Headline") + .size(HeadlineSize::XLarge) + .into_any_element(), + ), + single_example( + "Large", + Headline::new("Large Headline") + .size(HeadlineSize::Large) + .into_any_element(), + ), + single_example( + "Medium (Default)", + Headline::new("Medium Headline").into_any_element(), + ), + single_example( + "Small", + Headline::new("Small Headline") + .size(HeadlineSize::Small) + .into_any_element(), + ), + single_example( + "XSmall", + Headline::new("XSmall Headline") + .size(HeadlineSize::XSmall) + .into_any_element(), + ), + ]) + .into_any_element() } } diff --git a/crates/ui_input/src/input_field.rs b/crates/ui_input/src/input_field.rs index 16932b58e87cb9..8a95651950af3d 100644 --- a/crates/ui_input/src/input_field.rs +++ b/crates/ui_input/src/input_field.rs @@ -224,7 +224,13 @@ impl Component for InputField { ComponentScope::Input } - fn preview(window: &mut Window, cx: &mut App) -> Option { + fn description() -> &'static str { + "A single-line text field used for search inputs, \ + form fields, and similar inputs, supporting labels, placeholders, \ + leading icons, and masked content." + } + + fn preview(window: &mut Window, cx: &mut App) -> AnyElement { let input_small = cx.new(|cx| InputField::new(window, cx, "placeholder").label("Small Label")); @@ -234,20 +240,18 @@ impl Component for InputField { .label_size(LabelSize::Default) }); - Some( - v_flex() - .gap_6() - .children(vec![example_group(vec![ - single_example( - "Small Label (Default)", - div().child(input_small).into_any_element(), - ), - single_example( - "Regular Label", - div().child(input_regular).into_any_element(), - ), - ])]) - .into_any_element(), - ) + v_flex() + .gap_6() + .children(vec![example_group(vec![ + single_example( + "Small Label (Default)", + div().child(input_small).into_any_element(), + ), + single_example( + "Regular Label", + div().child(input_regular).into_any_element(), + ), + ])]) + .into_any_element() } } diff --git a/crates/workspace/src/notifications.rs b/crates/workspace/src/notifications.rs index 689160b435f901..ffe70b8301b851 100644 --- a/crates/workspace/src/notifications.rs +++ b/crates/workspace/src/notifications.rs @@ -697,7 +697,26 @@ impl RenderOnce for NotificationFrame { } } -impl Component for NotificationFrame {} +impl Component for NotificationFrame { + fn description() -> &'static str { + "The standard container used by workspace notifications, \ + providing a consistent title row, close and suppress affordances, \ + and a slot for the notification's contents." + } + + fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { + single_example( + "Default", + NotificationFrame::new() + .with_title(Some("Notification Title")) + .with_content(Label::new( + "This is the content of a workspace notification.", + )) + .into_any_element(), + ) + .into_any_element() + } +} pub mod simple_message_notification { use std::sync::Arc; From 676cb6675ecb9c2a9f00224afa83735bbfc0e1f6 Mon Sep 17 00:00:00 2001 From: MrSubidubi Date: Wed, 27 May 2026 01:05:37 +0200 Subject: [PATCH 2/3] Fix doctests --- crates/ui_macros/src/ui_macros.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/ui_macros/src/ui_macros.rs b/crates/ui_macros/src/ui_macros.rs index ce48a21c1155b2..75c1db3a5ee147 100644 --- a/crates/ui_macros/src/ui_macros.rs +++ b/crates/ui_macros/src/ui_macros.rs @@ -19,14 +19,20 @@ pub fn derive_dynamic_spacing(input: TokenStream) -> TokenStream { /// # Example /// /// ``` -/// use ui::Component; +/// use ui::{AnyElement, App, Component, div, IntoElement, Window}; /// use ui_macros::RegisterComponent; /// /// #[derive(RegisterComponent)] /// struct MyComponent; /// /// impl Component for MyComponent { -/// // Component implementation +/// fn description() -> &'static str { +/// "My component description" +/// } +/// +/// fn preview(_window: &mut Window, cx: &mut App) -> AnyElement { +/// div().into_any_element() +/// } /// } /// ``` /// From 7dead3086f845d8e3ab038768f166d6e577cba95 Mon Sep 17 00:00:00 2001 From: MrSubidubi Date: Thu, 28 May 2026 23:37:26 +0200 Subject: [PATCH 3/3] Review feedback --- crates/git_ui/src/git_panel.rs | 4 +- .../ui/src/components/button/icon_button.rs | 15 +++- crates/ui/src/components/keybinding.rs | 79 +++++++++++++------ 3 files changed, 69 insertions(+), 29 deletions(-) diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index 46382ee2010801..922624917f185d 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -7103,9 +7103,7 @@ impl Component for PanelRepoFooter { } fn description() -> &'static str { - "The footer shown at the bottom of the git panel, \ - displaying the active repository, current branch, and \ - upstream tracking status alongside fetch, pull, and push controls." + "The footer shown at the bottom of the git panel." } fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { diff --git a/crates/ui/src/components/button/icon_button.rs b/crates/ui/src/components/button/icon_button.rs index 844bdb007e21ff..246f46b911edca 100644 --- a/crates/ui/src/components/button/icon_button.rs +++ b/crates/ui/src/components/button/icon_button.rs @@ -2,7 +2,8 @@ use gpui::{AnyView, DefiniteLength, Hsla}; use super::button_like::{ButtonCommon, ButtonLike, ButtonSize, ButtonStyle}; use crate::{ - ElevationIndex, Icon, IconWithIndicator, Indicator, SelectableButton, TintColor, prelude::*, + ElevationIndex, Icon, IconWithIndicator, Indicator, SelectableButton, TintColor, Tooltip, + prelude::*, }; use crate::{IconName, IconSize}; @@ -241,8 +242,8 @@ impl Component for IconButton { } fn description() -> &'static str { - "A compact button that displays a single icon, used for actions where a \ - textual label would be redundant or take too much space." + "A compact button that displays a single icon with an optional tooltip.\ + The most frequently used button in the Zed codebase." } fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement { @@ -373,6 +374,14 @@ impl Component for IconButton { .layer(ElevationIndex::Background) .into_any_element(), ), + single_example( + "With Tooltip", + IconButton::new("tooltip", IconName::Check) + .style(ButtonStyle::Filled) + .layer(ElevationIndex::Background) + .tooltip(Tooltip::text("As mentioned - with a tooltip")) + .into_any_element(), + ), ], ), example_group_with_title( diff --git a/crates/ui/src/components/keybinding.rs b/crates/ui/src/components/keybinding.rs index eaf0de1e602fff..af30dd6865944b 100644 --- a/crates/ui/src/components/keybinding.rs +++ b/crates/ui/src/components/keybinding.rs @@ -130,6 +130,11 @@ impl KeyBinding { self.disabled = disabled; self } + + fn vim_mode(mut self, vim_mode: bool) -> Self { + self.vim_mode = vim_mode; + self + } } fn render_key( @@ -581,29 +586,57 @@ impl Component for KeyBinding { v_flex() .gap_6() - .children(vec![example_group_with_title( - "Platform Styles", - vec![ - single_example( - "Mac Style", - keybinding("cmd-s") - .platform_style(PlatformStyle::Mac) - .into_any_element(), - ), - single_example( - "Linux Style", - keybinding("ctrl-s") - .platform_style(PlatformStyle::Linux) - .into_any_element(), - ), - single_example( - "Windows Style", - keybinding("ctrl-s") - .platform_style(PlatformStyle::Windows) - .into_any_element(), - ), - ], - )]) + .children(vec![ + example_group_with_title( + "Platform Styles", + vec![ + single_example( + "Mac Style", + keybinding("cmd-s") + .platform_style(PlatformStyle::Mac) + .into_any_element(), + ), + single_example( + "Linux Style", + keybinding("ctrl-s") + .platform_style(PlatformStyle::Linux) + .into_any_element(), + ), + single_example( + "Windows Style", + keybinding("ctrl-s") + .platform_style(PlatformStyle::Windows) + .into_any_element(), + ), + ], + ), + example_group_with_title( + "Vim Mode Style", + vec![ + single_example( + "Simple", + keybinding("s") + .platform_style(PlatformStyle::Mac) + .vim_mode(true) + .into_any_element(), + ), + single_example( + "With Modifiers", + keybinding("ctrl-s") + .platform_style(PlatformStyle::Linux) + .vim_mode(true) + .into_any_element(), + ), + single_example( + "With other special key", + keybinding("ctrl-escape") + .platform_style(PlatformStyle::Windows) + .vim_mode(true) + .into_any_element(), + ), + ], + ), + ]) .into_any_element() } }