From 4dc10165fba339f4bb2f7770235b5d65b788f7cf Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Thu, 6 Nov 2025 11:36:39 +0800 Subject: [PATCH] spinner: Rename Indicator to Spinner. (#1526) ## Break Change - Renamed `Indicator` to `Spinner`. ```diff - use gpui_component::indicator::Indicator; + use gpui_component::spinner::Spinner; ``` --- crates/story/src/lib.rs | 4 +- crates/story/src/main.rs | 2 +- .../{indicator_story.rs => spinner_story.rs} | 49 +++---- crates/story/src/table_story.rs | 7 +- crates/ui/src/button/button.rs | 4 +- crates/ui/src/input/input.rs | 4 +- crates/ui/src/input/state.rs | 2 +- crates/ui/src/lib.rs | 2 +- crates/ui/src/{indicator.rs => spinner.rs} | 16 +-- docs/docs/components/index.md | 2 +- .../components/{indicator.md => spinner.md} | 134 ++++++++---------- 11 files changed, 102 insertions(+), 124 deletions(-) rename crates/story/src/{indicator_story.rs => spinner_story.rs} (51%) rename crates/ui/src/{indicator.rs => spinner.rs} (84%) rename docs/docs/components/{indicator.md => spinner.md} (62%) diff --git a/crates/story/src/lib.rs b/crates/story/src/lib.rs index d892ee2c..a7f72ca8 100644 --- a/crates/story/src/lib.rs +++ b/crates/story/src/lib.rs @@ -18,7 +18,6 @@ mod form_story; mod group_box_story; mod icon_story; mod image_story; -mod indicator_story; mod input_story; mod kbd_story; mod label_story; @@ -37,6 +36,7 @@ mod select_story; mod sidebar_story; mod skeleton_story; mod slider_story; +mod spinner_story; mod switch_story; mod table_story; mod tabs_story; @@ -78,7 +78,6 @@ pub use form_story::FormStory; pub use group_box_story::GroupBoxStory; pub use icon_story::IconStory; pub use image_story::ImageStory; -pub use indicator_story::IndicatorStory; pub use input_story::InputStory; pub use kbd_story::KbdStory; pub use label_story::LabelStory; @@ -98,6 +97,7 @@ use serde::{Deserialize, Serialize}; pub use sidebar_story::SidebarStory; pub use skeleton_story::SkeletonStory; pub use slider_story::SliderStory; +pub use spinner_story::SpinnerStory; pub use switch_story::SwitchStory; pub use table_story::TableStory; pub use tabs_story::TabsStory; diff --git a/crates/story/src/main.rs b/crates/story/src/main.rs index 04493b6d..47bad9f0 100644 --- a/crates/story/src/main.rs +++ b/crates/story/src/main.rs @@ -54,7 +54,7 @@ impl Gallery { StoryContainer::panel::(window, cx), StoryContainer::panel::(window, cx), StoryContainer::panel::(window, cx), - StoryContainer::panel::(window, cx), + StoryContainer::panel::(window, cx), StoryContainer::panel::(window, cx), StoryContainer::panel::(window, cx), StoryContainer::panel::(window, cx), diff --git a/crates/story/src/indicator_story.rs b/crates/story/src/spinner_story.rs similarity index 51% rename from crates/story/src/indicator_story.rs rename to crates/story/src/spinner_story.rs index 2d5c2e67..a6884065 100644 --- a/crates/story/src/indicator_story.rs +++ b/crates/story/src/spinner_story.rs @@ -1,23 +1,23 @@ use gpui::{ - px, App, AppContext, Context, Entity, Focusable, IntoElement, ParentElement, Render, Styled, - Window, + App, AppContext, Context, Entity, Focusable, IntoElement, ParentElement, Render, Styled, + Window, px, }; -use gpui_component::{indicator::Indicator, v_flex, ActiveTheme as _, IconName, Sizable}; +use gpui_component::{ActiveTheme as _, IconName, Sizable, spinner::Spinner, v_flex}; use crate::section; -pub struct IndicatorStory { +pub struct SpinnerStory { focus_handle: gpui::FocusHandle, value: f32, } -impl super::Story for IndicatorStory { +impl super::Story for SpinnerStory { fn title() -> &'static str { - "Indicator" + "Spinner" } fn description() -> &'static str { - "Displays an indicator showing the completion progress of a task." + "Displays an spinner showing the completion progress of a task." } fn new_view(window: &mut Window, cx: &mut App) -> Entity { @@ -25,7 +25,7 @@ impl super::Story for IndicatorStory { } } -impl IndicatorStory { +impl SpinnerStory { pub fn view(window: &mut Window, cx: &mut App) -> Entity { cx.new(|cx| Self::new(window, cx)) } @@ -42,39 +42,40 @@ impl IndicatorStory { } } -impl Focusable for IndicatorStory { +impl Focusable for SpinnerStory { fn focus_handle(&self, _: &gpui::App) -> gpui::FocusHandle { self.focus_handle.clone() } } -impl Render for IndicatorStory { +impl Render for SpinnerStory { fn render(&mut self, _: &mut Window, cx: &mut Context) -> impl IntoElement { v_flex() .items_center() - .gap_y_3() - .child(section("Indicator").gap_x_2().child(Indicator::new())) + .size_full() + .gap_6() + .child(section("Spinner").gap_x_2().child(Spinner::new())) .child( - section("Indicator with color") + section("Spinner with color") .gap_x_2() - .child(Indicator::new().color(cx.theme().blue)) - .child(Indicator::new().color(cx.theme().green)), + .child(Spinner::new().color(cx.theme().blue)) + .child(Spinner::new().color(cx.theme().green)), ) .child( - section("Indicator with size") + section("Spinner with size") .gap_x_2() - .child(Indicator::new().with_size(px(64.))) - .child(Indicator::new().large()) - .child(Indicator::new()) - .child(Indicator::new().small()) - .child(Indicator::new().xsmall()), + .child(Spinner::new().with_size(px(64.))) + .child(Spinner::new().large()) + .child(Spinner::new()) + .child(Spinner::new().small()) + .child(Spinner::new().xsmall()), ) .child( - section("Indicator with Icon") + section("Spinner with Icon") .gap_x_2() - .child(Indicator::new().icon(IconName::LoaderCircle)) + .child(Spinner::new().icon(IconName::LoaderCircle)) .child( - Indicator::new() + Spinner::new() .icon(IconName::LoaderCircle) .large() .color(cx.theme().cyan), diff --git a/crates/story/src/table_story.rs b/crates/story/src/table_story.rs index 8c50a591..18359552 100644 --- a/crates/story/src/table_story.rs +++ b/crates/story/src/table_story.rs @@ -16,10 +16,10 @@ use gpui_component::{ button::Button, checkbox::Checkbox, h_flex, - indicator::Indicator, input::{Input, InputEvent, InputState}, label::Label, menu::{DropdownMenu, PopupMenu}, + spinner::Spinner, table::{Column, ColumnFixed, ColumnSort, Table, TableDelegate, TableEvent, TableState}, v_flex, }; @@ -942,10 +942,7 @@ impl Render for TableStory { ) .when(delegate.loading, |this| { this.child( - h_flex() - .gap_1() - .child(Indicator::new()) - .child("Loading..."), + h_flex().gap_1().child(Spinner::new()).child("Loading..."), ) }), ) diff --git a/crates/ui/src/button/button.rs b/crates/ui/src/button/button.rs index 4f6b92a1..34af15df 100644 --- a/crates/ui/src/button/button.rs +++ b/crates/ui/src/button/button.rs @@ -1,7 +1,7 @@ use std::rc::Rc; use crate::{ - h_flex, indicator::Indicator, tooltip::Tooltip, ActiveTheme, Colorize as _, Disableable, + h_flex, spinner::Spinner, tooltip::Tooltip, ActiveTheme, Colorize as _, Disableable, FocusableExt as _, Icon, Selectable, Sizable, Size, StyleSized, StyledExt, }; use gpui::{ @@ -562,7 +562,7 @@ impl RenderOnce for Button { }) .when(self.loading, |this| { this.child( - Indicator::new() + Spinner::new() .with_size(self.size) .when_some(self.loading_icon, |this, icon| this.icon(icon)), ) diff --git a/crates/ui/src/input/input.rs b/crates/ui/src/input/input.rs index b6cf58a0..0d78a20a 100644 --- a/crates/ui/src/input/input.rs +++ b/crates/ui/src/input/input.rs @@ -6,10 +6,10 @@ use gpui::{ }; use crate::button::{Button, ButtonVariants as _}; -use crate::indicator::Indicator; use crate::input::clear_button; use crate::input::element::{LINE_NUMBER_RIGHT_MARGIN, RIGHT_MARGIN}; use crate::scroll::Scrollbar; +use crate::spinner::Spinner; use crate::{h_flex, Selectable, StyledExt}; use crate::{v_flex, ActiveTheme}; use crate::{IconName, Size}; @@ -406,7 +406,7 @@ impl RenderOnce for Input { .when(self.appearance, |this| this.bg(bg)) .items_center() .when(state.loading, |this| { - this.child(Indicator::new().color(cx.theme().muted_foreground)) + this.child(Spinner::new().color(cx.theme().muted_foreground)) }) .when(self.mask_toggle, |this| { this.child(Self::render_toggle_mask_button(self.state.clone())) diff --git a/crates/ui/src/input/state.rs b/crates/ui/src/input/state.rs index fbb8dfa7..58545566 100644 --- a/crates/ui/src/input/state.rs +++ b/crates/ui/src/input/state.rs @@ -771,7 +771,7 @@ impl InputState { self } - /// Set true to show indicator at the input right. + /// Set true to show spinner at the input right. /// /// Only for [`InputMode::SingleLine`] mode. pub fn set_loading(&mut self, loading: bool, _: &mut Window, cx: &mut Context) { diff --git a/crates/ui/src/lib.rs b/crates/ui/src/lib.rs index bfacd394..3ee25585 100644 --- a/crates/ui/src/lib.rs +++ b/crates/ui/src/lib.rs @@ -36,7 +36,6 @@ pub mod form; pub mod group_box; pub mod highlighter; pub mod history; -pub mod indicator; pub mod input; pub mod kbd; pub mod label; @@ -55,6 +54,7 @@ pub mod select; pub mod sidebar; pub mod skeleton; pub mod slider; +pub mod spinner; pub mod switch; pub mod tab; pub mod table; diff --git a/crates/ui/src/indicator.rs b/crates/ui/src/spinner.rs similarity index 84% rename from crates/ui/src/indicator.rs rename to crates/ui/src/spinner.rs index 9d46caad..3a8be3f0 100644 --- a/crates/ui/src/indicator.rs +++ b/crates/ui/src/spinner.rs @@ -6,17 +6,17 @@ use gpui::{ Hsla, IntoElement, ParentElement, RenderOnce, Styled as _, Transformation, Window, }; -/// A cycling loading indicator. +/// A cycling loading spinner. #[derive(IntoElement)] -pub struct Indicator { +pub struct Spinner { size: Size, icon: Icon, speed: Duration, color: Option, } -impl Indicator { - /// Create a new loading indicator. +impl Spinner { + /// Create a new loading spinner. pub fn new() -> Self { Self { size: Size::Medium, @@ -26,11 +26,11 @@ impl Indicator { } } - /// Set specified icon for the indicator. + /// Set specified icon for the spinner. /// /// Default is [`IconName::Loader`]. /// - /// Please ensure the icon used is suitable for a loading indicator. + /// Please ensure the icon used is suitable for a loading spinner. pub fn icon(mut self, icon: impl Into) -> Self { self.icon = icon.into(); self @@ -43,14 +43,14 @@ impl Indicator { } } -impl Sizable for Indicator { +impl Sizable for Spinner { fn with_size(mut self, size: impl Into) -> Self { self.size = size.into(); self } } -impl RenderOnce for Indicator { +impl RenderOnce for Spinner { fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement { div() .child( diff --git a/docs/docs/components/index.md b/docs/docs/components/index.md index 101350bc..14c2afb2 100644 --- a/docs/docs/components/index.md +++ b/docs/docs/components/index.md @@ -17,13 +17,13 @@ collapsed: false - [Collapsible](collapsible) - Expandable/collapsible content - [Icon](icon) - Icon display component - [Image](image) - Image display with fallbacks -- [Indicator](indicator) - Loading and status indicators - [Kbd](kbd) - Keyboard shortcut display - [Label](label) - Text labels for form elements - [Progress](progress) - Progress bars - [Radio](radio) - Single selection from multiple options - [Skeleton](skeleton) - Loading placeholders - [Slider](slider) - Value selection from a range +- [Spinner](spinner) - Loading and status spinners - [Switch](switch) - Toggle on/off control - [Tag](tag) - Labels and categories - [Toggle](toggle) - Toggle button states diff --git a/docs/docs/components/indicator.md b/docs/docs/components/spinner.md similarity index 62% rename from docs/docs/components/indicator.md rename to docs/docs/components/spinner.md index 2caca1f5..c703161f 100644 --- a/docs/docs/components/indicator.md +++ b/docs/docs/components/spinner.md @@ -1,93 +1,93 @@ --- -title: Indicator -description: Displays an animated loading indicator showing the completion progress of a task. +title: Spinner +description: Displays an animated loading showing the completion progress of a task. --- -# Indicator +# Spinner -A versatile indicator component that displays an animated loading spinner. Perfect for showing loading states, progress indicators, and other visual feedback during asynchronous operations. Features customizable icons, colors, sizes, and rotation animations. +Spinner element displays an animated loading. Perfect for showing loading states, progress spinners, and other visual feedback during asynchronous operations. Features customizable icons, colors, sizes, and rotation animations. ## Import ```rust -use gpui_component::indicator::Indicator; +use gpui_component::spinner::Spinner; ``` ## Usage -### Basic Indicator +### Basic ```rust // Default loader icon -Indicator::new() +Spinner::new() ``` -### Indicator with Custom Color +### Spinner with Custom Color ```rust use gpui_component::ActiveTheme; -// Blue indicator -Indicator::new() +// Blue spinner +Spinner::new() .color(cx.theme().blue) -// Green indicator for success states -Indicator::new() +// Green spinner for success states +Spinner::new() .color(cx.theme().green) // Custom color -Indicator::new() +Spinner::new() .color(cx.theme().cyan) ``` -### Indicator Sizes +### Spinner Sizes ```rust -// Extra small indicator -Indicator::new().xsmall() +// Extra small spinner +Spinner::new().xsmall() -// Small indicator -Indicator::new().small() +// Small spinner +Spinner::new().small() -// Medium indicator (default) -Indicator::new() +// Medium spinner (default) +Spinner::new() -// Large indicator -Indicator::new().large() +// Large spinner +Spinner::new().large() // Custom size -Indicator::new().with_size(px(64.)) +Spinner::new().with_size(px(64.)) ``` -### Indicator with Custom Icon +### Spinner with Custom Icon ```rust use gpui_component::IconName; // Loading circle icon -Indicator::new() +Spinner::new() .icon(IconName::LoaderCircle) // Large loading circle with custom color -Indicator::new() +Spinner::new() .icon(IconName::LoaderCircle) .large() .color(cx.theme().cyan) // Different loading icons -Indicator::new() +Spinner::new() .icon(IconName::Loader) .color(cx.theme().primary) ``` ## Available Icons -The Indicator component supports various loading and progress icons: +The Spinner component supports various loading and progress icons: ### Loading Icons - `Loader` (default) - Rotating line spinner -- `LoaderCircle` - Circular loading indicator +- `LoaderCircle` - Circular loading spinner ### Other Compatible Icons @@ -95,7 +95,7 @@ The Indicator component supports various loading and progress icons: ## Animation -The Indicator component features a built-in rotation animation: +The Spinner component features a built-in rotation animation: - **Duration**: 0.8 seconds (configurable via speed parameter) - **Easing**: Ease-in-out transition @@ -112,40 +112,20 @@ The Indicator component features a built-in rotation animation: | Large | `.large()` | ~24px | | Custom | `.with_size(px(n))` | n px | -## API Reference - -### Indicator - -| Method | Description | -| -------------- | ----------------------------------------------- | -| `new()` | Create a new indicator with default loader icon | -| `icon(icon)` | Set custom icon (accepts `IconName` or `Icon`) | -| `color(color)` | Set indicator color (accepts `Hsla`) | - -### Size Methods (from Sizable trait) - -| Method | Description | -| ----------------- | ------------------------------- | -| `xsmall()` | Extra small indicator size | -| `small()` | Small indicator size | -| `medium()` | Medium indicator size (default) | -| `large()` | Large indicator size | -| `with_size(size)` | Custom size in pixels | - ## Examples ### Loading States ```rust // Simple loading spinner -Indicator::new() +Spinner::new() // Loading with custom color -Indicator::new() +Spinner::new() .color(cx.theme().blue) -// Large loading indicator -Indicator::new() +// Large loading spinner +Spinner::new() .large() .color(cx.theme().primary) ``` @@ -154,36 +134,36 @@ Indicator::new() ```rust // Default loader (line spinner) -Indicator::new() +Spinner::new() .color(cx.theme().muted_foreground) // Circle loader -Indicator::new() +Spinner::new() .icon(IconName::LoaderCircle) .color(cx.theme().blue) // Large circle loader with custom color -Indicator::new() +Spinner::new() .icon(IconName::LoaderCircle) .large() .color(cx.theme().green) ``` -### Status Indicators +### Status Spinners ```rust // Loading state -Indicator::new() +Spinner::new() .small() .color(cx.theme().muted_foreground) // Processing state -Indicator::new() +Spinner::new() .icon(IconName::LoaderCircle) .color(cx.theme().blue) // Success processing (still animating) -Indicator::new() +Spinner::new() .icon(IconName::LoaderCircle) .color(cx.theme().green) ``` @@ -192,26 +172,26 @@ Indicator::new() ```rust // Extra small for inline text -Indicator::new() +Spinner::new() .xsmall() .color(cx.theme().muted_foreground) // Small for buttons -Indicator::new() +Spinner::new() .small() .color(cx.theme().primary_foreground) // Medium for general use (default) -Indicator::new() +Spinner::new() .color(cx.theme().primary) // Large for prominent loading states -Indicator::new() +Spinner::new() .large() .color(cx.theme().blue) // Custom size for specific requirements -Indicator::new() +Spinner::new() .with_size(px(32.)) .color(cx.theme().orange) ``` @@ -223,7 +203,7 @@ Indicator::new() Button::new("submit-btn") .loading(true) .icon( - Indicator::new() + Spinner::new() .small() .color(cx.theme().primary_foreground) ) @@ -236,7 +216,7 @@ div() .gap_2() .child("Processing...") .child( - Indicator::new() + Spinner::new() .small() .color(cx.theme().muted_foreground) ) @@ -249,7 +229,7 @@ div() .h_full() .w_full() .child( - Indicator::new() + Spinner::new() .large() .color(cx.theme().primary) ) @@ -258,19 +238,19 @@ div() ## Performance Considerations - The animation uses CSS transforms for optimal performance -- Multiple indicators on the same page share the same animation timing +- Multiple spinners on the same page share the same animation timing - The component is lightweight and suitable for frequent updates -- Consider using smaller sizes for better performance with many indicators +- Consider using smaller sizes for better performance with many spinners ## Common Patterns ### Conditional Loading ```rust -// Show indicator only when loading +// Show spinner only when loading .when(is_loading, |this| { this.child( - Indicator::new() + Spinner::new() .small() .color(cx.theme().muted_foreground) ) @@ -280,12 +260,12 @@ div() ### Loading with Text ```rust -// Loading text with indicator +// Loading text with spinner h_flex() .items_center() .gap_2() .child( - Indicator::new() + Spinner::new() .small() .color(cx.theme().primary) ) @@ -295,7 +275,7 @@ h_flex() ### Overlay Loading ```rust -// Full overlay with indicator +// Full overlay with spinner div() .absolute() .inset_0() @@ -308,7 +288,7 @@ div() .items_center() .gap_3() .child( - Indicator::new() + Spinner::new() .large() .color(cx.theme().primary) )