From b08b6d6ecef40eb2c709b87482154cb093f2b186 Mon Sep 17 00:00:00 2001 From: InfamousVague Date: Fri, 12 Jan 2024 13:41:48 -0500 Subject: [PATCH] feat(LoadingIndicator): Added spinning loading indicator --- icons/src/icons/outline/loader.svg | 6 ++-- kit/src/elements/button/mod.rs | 9 +++++- kit/src/elements/input/mod.rs | 5 ++- kit/src/elements/loader/mod.rs | 21 +++++++++++++ kit/src/elements/loader/style.scss | 31 +++++++++++++++++++ kit/src/elements/mod.rs | 1 + .../chats/presentation/messages/mod.rs | 10 +++--- ui/src/layouts/log_in/entry_point.rs | 2 +- 8 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 kit/src/elements/loader/mod.rs create mode 100644 kit/src/elements/loader/style.scss diff --git a/icons/src/icons/outline/loader.svg b/icons/src/icons/outline/loader.svg index 93446e86ffd..34963c577ea 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 + + + \ 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..90ebfebd02f 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: if *cmd_in_progress.get() { true } else { false }, disabled: *cmd_in_progress.current() || validation_failure.current().is_some(), onpress: move |_| { // these are only for testing.