freya_components/
loader.rs1use freya_animation::prelude::*;
2use freya_core::prelude::*;
3use torin::size::Size;
4
5use crate::{
6 cache::AssetAge,
7 define_theme,
8 get_theme,
9 svg_viewer::SvgViewer,
10};
11
12define_theme! {
13 %[component]
14 pub CircularLoader {
15 %[fields]
16 primary_color: Color,
17 }
18}
19
20#[derive(PartialEq)]
33pub struct CircularLoader {
34 pub(crate) theme: Option<CircularLoaderThemePartial>,
35 size: f32,
36 accessibility: AccessibilityData,
37 key: DiffKey,
38}
39
40impl KeyExt for CircularLoader {
41 fn key_mut(&mut self) -> &mut DiffKey {
42 &mut self.key
43 }
44}
45
46impl AccessibilityExt for CircularLoader {
47 fn accessibility_data_mut(&mut self) -> &mut AccessibilityData {
48 &mut self.accessibility
49 }
50}
51
52impl Default for CircularLoader {
53 fn default() -> Self {
54 Self::new()
55 }
56}
57
58impl CircularLoader {
59 pub fn new() -> Self {
60 Self {
61 size: 32.,
62 theme: None,
63 accessibility: AccessibilityData::default(),
64 key: DiffKey::None,
65 }
66 }
67
68 pub fn size(mut self, size: f32) -> Self {
69 self.size = size;
70 self
71 }
72}
73
74impl Component for CircularLoader {
75 fn render(&self) -> impl IntoElement {
76 let theme = get_theme!(
77 &self.theme,
78 CircularLoaderThemePreference,
79 "circular_loader"
80 );
81
82 let animation = use_animation(|conf| {
83 conf.on_creation(OnCreation::Run);
84 conf.on_finish(OnFinish::restart());
85 AnimNum::new(0.0, 360.0).time(650)
86 });
87
88 SvgViewer::new(
89 r#"<svg viewBox="0 0 600 600" xmlns="http://www.w3.org/2000/svg">
90 <circle class="spin" cx="300" cy="300" fill="none"
91 r="250" stroke-width="64" stroke="{color}"
92 stroke-dasharray="256 1400"
93 stroke-linecap="round" />
94 </svg>"#
95 .as_bytes(),
96 )
97 .show_loader(false)
98 .asset_age(AssetAge::zero())
99 .accessibility(self.accessibility.clone())
100 .a11y_role(AccessibilityRole::ProgressIndicator)
101 .width(Size::px(self.size))
102 .height(Size::px(self.size))
103 .stroke(theme.primary_color)
104 .rotation(animation.get().value())
105 }
106
107 fn render_key(&self) -> DiffKey {
108 self.key.clone().or(self.default_key())
109 }
110}