use gpui_kit::{
App, ElementId, InteractiveElement as _, IntoElement, ParentElement as _, RenderOnce, Role,
SharedString, StatefulInteractiveElement as _, StyleRefinement, Styled, TestSupportExt as _,
Window, base::StyledExt as _, div,
};
use crate::Progress;
#[derive(IntoElement)]
pub struct Spinner {
id: ElementId,
style: StyleRefinement,
accessibility_label: Option<SharedString>,
}
impl Spinner {
pub fn new(id: impl Into<ElementId>) -> Self {
Self {
id: id.into(),
style: StyleRefinement::default(),
accessibility_label: None,
}
}
pub fn accessibility_label(mut self, label: impl Into<SharedString>) -> Self {
self.accessibility_label = Some(label.into());
self
}
}
impl Styled for Spinner {
fn style(&mut self) -> &mut StyleRefinement {
&mut self.style
}
}
const DEFAULT_LABEL: &str = "Loading";
impl RenderOnce for Spinner {
fn render(self, _: &mut Window, _: &mut App) -> impl IntoElement {
let label = self
.accessibility_label
.unwrap_or_else(|| DEFAULT_LABEL.into());
div()
.id(self.id.clone())
.role(Role::Status)
.aria_label(label.clone())
.test_support()
.flex_shrink_0()
.size_4()
.refine_style(&self.style)
.child(
Progress::new(ElementId::NamedChild(self.id.into(), "arc".into()))
.circular()
.accessibility_label(label)
.size_full(),
)
}
}