diff --git a/icons/src/icons/outline/loader.svg b/icons/src/icons/outline/loader.svg
index 93446e86ffd..ecd2025e3d7 100644
--- a/icons/src/icons/outline/loader.svg
+++ b/icons/src/icons/outline/loader.svg
@@ -1,3 +1,3 @@
\ No newline at end of file
diff --git a/kit/src/elements/button/mod.rs b/kit/src/elements/button/mod.rs
index 976c0f345ae..65e6abf648a 100644
--- a/kit/src/elements/button/mod.rs
+++ b/kit/src/elements/button/mod.rs
@@ -1,6 +1,6 @@
use dioxus::{events::MouseEvent, prelude::*};
-use crate::elements::Appearance;
+use crate::elements::{loader::Loader, Appearance};
use common::icons::outline::Shape as Icon;
@@ -118,6 +118,13 @@ pub fn Button<'a>(cx: Scope<'a, Props<'a>>) -> Element<'a> {
let _ = cx.props.onpress.as_ref().map(|f| f.call(e));
}
},
+ if let Some(loading) = cx.props.loading {
+ loading.then(|| rsx!(
+ Loader {
+ spinning: true
+ }
+ ))
+ },
if let Some(_icon) = cx.props.icon {
rsx!(
// for props, copy the defaults passed in by IconButton
diff --git a/kit/src/elements/input/mod.rs b/kit/src/elements/input/mod.rs
index ad2ef1e09d8..daef1e8c973 100644
--- a/kit/src/elements/input/mod.rs
+++ b/kit/src/elements/input/mod.rs
@@ -7,6 +7,7 @@ use uuid::Uuid;
pub type ValidationError = String;
use crate::elements::label::Label;
+use crate::elements::loader::Loader;
use common::icons::outline::Shape as Icon;
use common::icons::Icon as IconElement;
@@ -483,9 +484,7 @@ pub fn Input<'a>(cx: Scope<'a, Props<'a>>) -> Element<'a> {
}
)),
cx.props.loading.unwrap_or(false).then(move || rsx!(
- IconElement {
- icon: Icon::Loader
- }
+ Loader { spinning: true },
)),
},
(!error.is_empty()).then(|| rsx!(
diff --git a/kit/src/elements/loader/mod.rs b/kit/src/elements/loader/mod.rs
new file mode 100644
index 00000000000..ad3323f806e
--- /dev/null
+++ b/kit/src/elements/loader/mod.rs
@@ -0,0 +1,21 @@
+use common::icons::outline::Shape as Icon;
+use common::icons::Icon as IconElement;
+use dioxus::prelude::*;
+
+#[derive(PartialEq, Eq, Props)]
+pub struct Props {
+ #[props(optional)]
+ spinning: Option,
+}
+
+#[allow(non_snake_case)]
+pub fn Loader(cx: Scope) -> Element {
+ cx.render(rsx!(
+ div {
+ class: "loader",
+ div {
+ class: "spin",
+ IconElement { icon: Icon::Loader }
+ }
+ }))
+}
diff --git a/kit/src/elements/loader/style.scss b/kit/src/elements/loader/style.scss
new file mode 100644
index 00000000000..2de80a389ee
--- /dev/null
+++ b/kit/src/elements/loader/style.scss
@@ -0,0 +1,31 @@
+.loader {
+ height: 20px;
+ width: 20px;
+ position: relative;
+ overflow: hidden;
+
+ .spin {
+ height: 20px;
+ width: 20px;
+ animation: spin 1s infinite ease-out;
+ top: 10px;
+ left: 10px;
+ position: relative;
+ display: inline-block;
+ }
+
+ svg {
+ fill: transparent;
+ stroke: var(--text-color);
+ }
+}
+
+@keyframes spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
diff --git a/kit/src/elements/mod.rs b/kit/src/elements/mod.rs
index d7e2e17fed1..7d05628f0f3 100644
--- a/kit/src/elements/mod.rs
+++ b/kit/src/elements/mod.rs
@@ -6,6 +6,7 @@ pub mod file;
pub mod folder;
pub mod input;
pub mod label;
+pub mod loader;
pub mod multiline;
pub mod radio_list;
pub mod range;
diff --git a/ui/src/layouts/chats/presentation/messages/mod.rs b/ui/src/layouts/chats/presentation/messages/mod.rs
index def084dd49d..0799b912d95 100644
--- a/ui/src/layouts/chats/presentation/messages/mod.rs
+++ b/ui/src/layouts/chats/presentation/messages/mod.rs
@@ -19,7 +19,10 @@ use kit::{
message_reply::MessageReply,
user_image::UserImage,
},
- elements::tooltip::{ArrowPosition, Tooltip},
+ elements::{
+ loader::Loader,
+ tooltip::{ArrowPosition, Tooltip},
+ },
};
use common::state::{pending_message::PendingMessage, Action, Identity, State};
@@ -102,9 +105,8 @@ pub fn get_messages(
rsx!(div {
class: "fetching",
p {
- IconElement {
- icon: Icon::Loader,
- class: "spin",
+ Loader {
+ spinning: true
},
get_local_text("messages.fetching")
}
diff --git a/ui/src/layouts/log_in/entry_point.rs b/ui/src/layouts/log_in/entry_point.rs
index 291ad5f5f6c..3f1cb31a1d7 100644
--- a/ui/src/layouts/log_in/entry_point.rs
+++ b/ui/src/layouts/log_in/entry_point.rs
@@ -264,7 +264,7 @@ pub fn Layout(cx: Scope, page: UseState, pin: UseRef) -> Elem
},
aria_label: "create-account-button".into(),
appearance: kit::elements::Appearance::Primary,
- icon: if *cmd_in_progress.get() {Icon::Loader} else {Icon::Check},
+ loading: *cmd_in_progress.get(),
disabled: *cmd_in_progress.current() || validation_failure.current().is_some(),
onpress: move |_| {
// these are only for testing.