Compare commits
3 Commits
46c251ef90
...
f52733d9a6
Author | SHA1 | Date | |
---|---|---|---|
f52733d9a6
|
|||
bb56d24f02
|
|||
043a721429
|
@@ -51,9 +51,17 @@ $color-ternary-70: #8B0046;
|
|||||||
$color-ternary-60: #720033;
|
$color-ternary-60: #720033;
|
||||||
$color-ternary-50: #5A0022;
|
$color-ternary-50: #5A0022;
|
||||||
|
|
||||||
|
$border-default-color: $greyscale-90;
|
||||||
|
$border-big-width: 4px;
|
||||||
|
$border-big: solid $border-big-width $border-default-color;
|
||||||
|
$border-normal-width: 2px;
|
||||||
|
$border-normal: solid $border-normal-width $border-default-color;
|
||||||
|
|
||||||
|
|
||||||
$form-max-height: 1024px;
|
$form-max-height: 1024px;
|
||||||
$form-aspect-ratio: 1/1.618;
|
$form-aspect-ratio: 1/1.618;
|
||||||
|
|
||||||
|
// TODO: Radius should be a percentage(eg: 1024/16px).
|
||||||
$border-radius: 16px;
|
$border-radius: 16px;
|
||||||
|
|
||||||
$geist-font-path: "../fonts/Geist";
|
$geist-font-path: "../fonts/Geist";
|
||||||
|
148
src/components/button.rs
Normal file
148
src/components/button.rs
Normal file
@@ -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<EventHandler<'a, MouseEvent>>,
|
||||||
|
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<EventHandler<'a, MouseEvent>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
44
src/components/button.scss
Normal file
44
src/components/button.scss
Normal file
@@ -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;
|
||||||
|
}
|
@@ -1,4 +1,5 @@
|
|||||||
pub mod avatar_selector;
|
pub mod avatar_selector;
|
||||||
|
pub mod button;
|
||||||
pub mod chats_window;
|
pub mod chats_window;
|
||||||
pub mod contacts_window;
|
pub mod contacts_window;
|
||||||
pub mod header;
|
pub mod header;
|
||||||
|
@@ -23,14 +23,21 @@ impl IconShape for _Spinner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[derive(PartialEq, Props)]
|
||||||
pub fn Spinner(cx: Scope) -> Element {
|
pub struct SpinnerProps {
|
||||||
|
#[props(default = true)]
|
||||||
|
animate: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Spinner(cx: Scope<SpinnerProps>) -> Element {
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
style { STYLE_SHEET },
|
style { STYLE_SHEET },
|
||||||
|
|
||||||
div {
|
div {
|
||||||
class: ClassName::ROOT,
|
class: ClassName::ROOT,
|
||||||
|
|
||||||
Icon {
|
Icon {
|
||||||
|
class: if cx.props.animate { "" } else { ClassName::PAUSED },
|
||||||
icon: _Spinner,
|
icon: _Spinner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -35,5 +35,10 @@ $logo-aspect-ratio: calc($logo-width / $logo-height);
|
|||||||
fill: $color-ternary-100;
|
fill: $color-ternary-100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.paused {
|
||||||
|
animation-play-state: paused;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user