diff --git a/src/components/button.rs b/src/components/button.rs new file mode 100644 index 0000000..caa6f8a --- /dev/null +++ b/src/components/button.rs @@ -0,0 +1,148 @@ +use dioxus::prelude::*; +use dioxus_free_icons::{Icon, IconShape}; + +turf::style_sheet!("src/components/button.scss"); + +#[derive(Props)] +struct _ButtonProps<'a> { + children: Element<'a>, + #[props(default = false)] + focus: bool, + #[props(optional)] + id: Option<&'a str>, + #[props(optional)] + onclick: Option>, + style: &'static str, +} + +fn Button<'a>(cx: Scope<'a, _ButtonProps<'a>>) -> Element<'a> { + let focus = cx.props.focus; + + cx.render(rsx! { + style { STYLE_SHEET }, + + button { + id: cx.props.id, + + class: cx.props.style, + + onmounted: move |cx| async move { + let _ = cx.inner().set_focus(focus).await; + }, + + onclick: move |evt| { + if let Some(cb) = &cx.props.onclick { + cb.call(evt); + } + }, + + &cx.props.children + } + }) +} + +#[derive(Copy, Clone, Debug)] +struct RegisterText; +impl IconShape for RegisterText { + fn view_box(&self) -> String { + String::from("0 0 250 50") + } + fn xmlns(&self) -> String { + String::from("http://www.w3.org/2000/svg") + } + fn child_elements(&self) -> LazyNodes { + rsx! { + text { + x: "50%", + y: "50%", + "dominant-baseline": "middle", + "text-anchor": "middle", + "font-size": "50", + style: "fill: #ffffff", + "Register" + } + } + } +} + +#[derive(Props)] +pub struct ButtonProps<'a> { + #[props(default = false)] + focus: bool, + #[props(optional)] + id: Option<&'a str>, + #[props(optional)] + onclick: Option>, +} + +pub fn RegisterButton<'a>(cx: Scope<'a, ButtonProps>) -> Element<'a> { + cx.render(rsx! { + style { STYLE_SHEET }, + + Button { + id: cx.props.id.unwrap_or(""), + + style: ClassName::REGISTER, + + onclick: |event| { + if let Some(cb) = &cx.props.onclick { + cb.call(event); + } + }, + + focus: cx.props.focus, + + Icon { + icon: RegisterText, + } + } + }) +} + +#[derive(Copy, Clone, Debug)] +struct LoginText; +impl IconShape for LoginText { + fn view_box(&self) -> String { + String::from("0 0 250 50") + } + fn xmlns(&self) -> String { + String::from("http://www.w3.org/2000/svg") + } + fn child_elements(&self) -> LazyNodes { + rsx! { + text { + x: "50%", + y: "50%", + "dominant-baseline": "middle", + "text-anchor": "middle", + "font-size": "50", + style: "fill: #ffffff", + "Login" + } + } + } +} + +pub fn LoginButton<'a>(cx: Scope<'a, ButtonProps>) -> Element<'a> { + cx.render(rsx! { + style { STYLE_SHEET }, + + Button { + id: cx.props.id.unwrap_or(""), + + style: ClassName::LOGIN, + + onclick: |event| { + if let Some(cb) = &cx.props.onclick { + cb.call(event); + } + }, + + focus: cx.props.focus, + + Icon { + icon: LoginText, + } + } + }) +} diff --git a/src/components/button.scss b/src/components/button.scss new file mode 100644 index 0000000..c2ac1d4 --- /dev/null +++ b/src/components/button.scss @@ -0,0 +1,44 @@ +@import "../_base.scss" + +.root { + height: 100%; + aspect-ratio: 3.5; + + border: $border-big; + border-radius: $border-radius; + + color: $greyscale-0; + + font-family: "Geist"; + font-weight: bold; + + svg { + height: 100%; + width: 100%; + } +} + +.register { + @extend .root; + + background-color: $color-ternary-90; +} +.register:hover { + background-color: $color-ternary-80; +} +.register:active { + background-color: $color-ternary-70; +} + + +.login { + @extend .root; + + background-color: $color-secondary-90; +} +.login:hover { + background-color: $color-secondary-80; +} +.login:active { + background-color: $color-secondary-70; +} diff --git a/src/components/mod.rs b/src/components/mod.rs index 2a4230e..857ab74 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -1,4 +1,5 @@ pub mod avatar_selector; +pub mod button; pub mod chats_window; pub mod contacts_window; pub mod header;