diff --git a/crates/site-app/src/components/icons.rs b/crates/site-app/src/components/icons.rs index 95d36d1a..c03c7efd 100644 --- a/crates/site-app/src/components/icons.rs +++ b/crates/site-app/src/components/icons.rs @@ -38,6 +38,25 @@ pub fn EnvelopeHeroIcon() -> impl IntoView { } } +#[component] +pub fn EyeHeroIcon() -> impl IntoView { + view! { + + + + + } +} + +#[component] +pub fn EyeSlashHeroIcon() -> impl IntoView { + view! { + + + + } +} + #[component] pub fn HashtagHeroIcon() -> impl IntoView { view! { @@ -47,6 +66,24 @@ pub fn HashtagHeroIcon() -> impl IntoView { } } +#[component] +pub fn GlobeAltHeroIcon() -> impl IntoView { + view! { + + + + } +} + +#[component] +pub fn KeyHeroIcon() -> impl IntoView { + view! { + + + + } +} + #[component] pub fn LockClosedHeroIcon() -> impl IntoView { view! { diff --git a/crates/site-app/src/components/input_field.rs b/crates/site-app/src/components/input_field.rs index c4228bc9..6cdc33cd 100644 --- a/crates/site-app/src/components/input_field.rs +++ b/crates/site-app/src/components/input_field.rs @@ -1,47 +1,79 @@ mod specialized; -use leptos::{ev::Event, prelude::*}; +use leptos::{ + ev::{Event, MouseEvent}, + prelude::*, +}; pub use self::specialized::*; use crate::components::{ - icons::LockClosedHeroIcon, ArchiveBoxHeroIcon, EnvelopeHeroIcon, UserHeroIcon, + icons::LockClosedHeroIcon, ArchiveBoxHeroIcon, EnvelopeHeroIcon, EyeHeroIcon, + EyeSlashHeroIcon, GlobeAltHeroIcon, KeyHeroIcon, UserHeroIcon, }; #[derive(Clone, Copy)] pub enum InputIcon { ArchiveBox, Envelope, + Eye, + EyeSlash, + GlobeAlt, + Key, LockClosed, User, } -impl IntoAny for InputIcon { - fn into_any(self) -> AnyView { - match self { - InputIcon::ArchiveBox => { - view! { }.into_any() - } - InputIcon::Envelope => { - view! { }.into_any() - } - InputIcon::LockClosed => { - view! { }.into_any() - } - InputIcon::User => { - view! { }.into_any() - } +macro_rules! icon_match { + ($self_expr:expr, $click_handler:expr, $icon_class:expr, { + $($variant:ident => $component:ident),* $(,)? + }) => { + match $self_expr { + $( + InputIcon::$variant => view! { + <$component {..} class=$icon_class on:click=$click_handler /> + }.into_any(), + )* } + }; +} + +impl InputIcon { + fn into_any(self, click_handler: Option>) -> AnyView { + const ICON_CLASS: &str = "size-6"; + + let click_handler = move |e| { + if let Some(h) = click_handler { + h.run(e) + } + }; + + icon_match!(self, click_handler, ICON_CLASS, { + ArchiveBox => ArchiveBoxHeroIcon, + Envelope => EnvelopeHeroIcon, + Eye => EyeHeroIcon, + EyeSlash => EyeSlashHeroIcon, + GlobeAlt => GlobeAltHeroIcon, + Key => KeyHeroIcon, + LockClosed => LockClosedHeroIcon, + User => UserHeroIcon, + }) } } #[component] pub fn InputField( - id: &'static str, - label_text: &'static str, - input_type: &'static str, - placeholder: &'static str, - #[prop(optional_no_strip)] before: Option, - #[prop(optional_no_strip)] after: Option, + #[prop(into)] id: Signal<&'static str>, + #[prop(into)] label_text: Signal<&'static str>, + #[prop(into)] input_type: Signal<&'static str>, + #[prop(into)] placeholder: Signal<&'static str>, + #[prop(into, optional_no_strip)] before: MaybeProp, + #[prop(into, optional_no_strip)] after: MaybeProp, + #[prop(into, optional_no_strip)] before_click_callback: Option< + Callback, + >, + #[prop(into, optional_no_strip)] after_click_callback: Option< + Callback, + >, input_signal: impl Fn() -> String + Send + 'static, output_signal: impl Fn(Event) + Send + 'static, #[prop(default = false)] autofocus: bool, @@ -60,13 +92,13 @@ pub fn InputField(