From f6018800d3b3ee7e250f1541412dd62293b6a71b Mon Sep 17 00:00:00 2001 From: Andres Suarez Date: Mon, 26 Jan 2026 16:26:25 -0800 Subject: [PATCH] project: Add spinner while search is underway (#47620) When there are no search results, it's clear that a search is still ongoing because the landing page says "Searching...". However, once there's at least one result found, it becomes completely unclear when search is actually finished. This adds a spinner immediately to the right of the result counter that stops once the search is finished. https://github.com/user-attachments/assets/a0ca4e2a-c506-42a4-bc4b-c1eb32d69e79 Release Notes: - Added spinner to project search, indicating that a search is still ongoing. --------- Co-authored-by: Danilo Leal --- crates/search/src/project_search.rs | 39 +++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 0bb58e43e5bd21460f0b2338e1408bac5e3447fd..c2d90c11ef4e68095c12788d2e8c0c99eccd6e37 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -40,7 +40,10 @@ use std::{ pin::pin, sync::Arc, }; -use ui::{IconButtonShape, KeyBinding, Toggleable, Tooltip, prelude::*, utils::SearchInputWidth}; +use ui::{ + CommonAnimationExt, IconButtonShape, KeyBinding, Toggleable, Tooltip, prelude::*, + utils::SearchInputWidth, +}; use util::{ResultExt as _, paths::PathMatcher, rel_path::RelPath}; use workspace::{ DeploySearch, ItemNavHistory, NewSearch, ToolbarItemEvent, ToolbarItemLocation, @@ -2013,6 +2016,7 @@ impl Render for ProjectSearchBar { let theme_colors = cx.theme().colors(); let project_search = search.entity.read(cx); let limit_reached = project_search.limit_reached; + let is_search_underway = project_search.pending_search.is_some(); let color_override = match ( &project_search.pending_search, @@ -2105,16 +2109,29 @@ impl Render for ProjectSearchBar { .id("matches") .ml_2() .min_w(rems_from_px(40.)) - .child(Label::new(match_text).size(LabelSize::Small).color( - if search.active_match_index.is_some() { - Color::Default - } else { - Color::Disabled - }, - )) - .when(limit_reached, |el| { - el.tooltip(Tooltip::text( - "Search limits reached.\nTry narrowing your search.", + .child( + h_flex() + .gap_1p5() + .child( + Label::new(match_text) + .size(LabelSize::Small) + .when(search.active_match_index.is_some(), |this| { + this.color(Color::Disabled) + }), + ) + .when(is_search_underway, |this| { + this.child( + Icon::new(IconName::ArrowCircle) + .color(Color::Accent) + .size(IconSize::Small) + .with_rotate_animation(2) + .into_any_element(), + ) + }), + ) + .when(limit_reached, |this| { + this.tooltip(Tooltip::text( + "Search Limits Reached\nTry narrowing your search", )) }), );