Skip to content

Commit 84f121d

Browse files
authored
Merge pull request #55 from RustLangES/leptos
Some Leptos Components
2 parents 23618b0 + 4cf9c02 commit 84f121d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1200
-6
lines changed

Cargo.lock

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[package]
22
name = "rustlanges-components"
33
version = "0.1.0"
4+
edition = "2024"
45

56
[lib]
67
path = "crates/lib.rs"
@@ -9,7 +10,8 @@ path = "crates/lib.rs"
910
leptos = ["leptos-components"]
1011

1112
[workspace]
12-
members = ["crates/leptos"]
13+
members = [ "crates/core", "crates/leptos" ]
1314

1415
[dependencies]
16+
components-core = { package = "rustlanges-components-core", version = "0.1.0", path = "./crates/core" }
1517
leptos-components = { path = "./crates/leptos", optional = true }

crates/core/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "rustlanges-components-core"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
constcat = "0.6.1"

crates/core/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub const BASE_CLASS: &str = "rustlanges";
2+
3+
pub use constcat::{concat, concat_bytes, concat_slices};

crates/leptos/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ edition = "2024"
55

66
[dependencies]
77
leptos = { version = "0.8.2", default-features = false }
8+
components-core = { package = "rustlanges-components-core", version = "0.1.0", path = "../core" }
89
tailwind_fuse = { version = "0.3", features = ["variant", "tailwind_fuse_macro"] }

crates/leptos/src/avatar.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use components_core::{BASE_CLASS, concat};
2+
use leptos::prelude::*;
3+
4+
#[component]
5+
pub fn Avatar(
6+
#[prop(into)] url: String,
7+
#[prop(into, optional)] alt: String,
8+
#[prop(into, optional, default = 32)] size: i32,
9+
#[prop(into, optional)] class: String,
10+
) -> impl IntoView {
11+
let class = crate::tw!(concat!(BASE_CLASS, "-avatar"), class);
12+
13+
view! {
14+
<div
15+
class={class}
16+
style:width={format!("{size}px")}
17+
style:height={format!("{size}px")}
18+
>
19+
<img class="rustlanges-avatar__img" src={url} alt={alt} />
20+
</div>
21+
}
22+
}

crates/leptos/src/badge.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use components_core::{BASE_CLASS, concat};
2+
use leptos::prelude::*;
3+
use leptos::{IntoView, component, view};
4+
5+
const LIMIT_NUMERIC: isize = 9;
6+
const LIMIT_NUMERIC_NEGATIVE: isize = -9;
7+
8+
#[derive(Default, Debug, PartialEq)]
9+
pub enum Variant {
10+
Completed,
11+
Reading,
12+
#[default]
13+
Pending,
14+
Unread,
15+
}
16+
17+
impl Variant {
18+
pub fn text(&self) -> &'static str {
19+
match self {
20+
Variant::Completed => "Completo",
21+
Variant::Reading => "Leyendo",
22+
Variant::Pending => "Pendiente",
23+
Variant::Unread => "No leido",
24+
}
25+
}
26+
}
27+
28+
#[derive(Default, Debug, PartialEq)]
29+
pub enum Type {
30+
#[default]
31+
Default,
32+
Numeric,
33+
Text,
34+
}
35+
36+
#[component]
37+
pub fn Badge(
38+
#[prop(into)] count: ReadSignal<isize>,
39+
#[prop(into, optional)] variant: Variant,
40+
#[prop(into, optional)] r#type: Type,
41+
) -> impl IntoView {
42+
let class = crate::tw!(
43+
concat!("text-paragraph-2 ", BASE_CLASS, "-badge"),
44+
format!("{BASE_CLASS}-badge--variant-{variant:?}"),
45+
format!("{BASE_CLASS}-badge--type-{type:?}"),
46+
);
47+
48+
let display_value = move || match r#type {
49+
Type::Default => count.get().to_string(),
50+
Type::Numeric => {
51+
let count = count.get();
52+
match count {
53+
..=LIMIT_NUMERIC_NEGATIVE => LIMIT_NUMERIC_NEGATIVE.to_string(),
54+
LIMIT_NUMERIC.. => format!("+{LIMIT_NUMERIC}"),
55+
_ => count.to_string(),
56+
}
57+
}
58+
Type::Text => variant.text().to_string(),
59+
};
60+
61+
view! {
62+
<div
63+
class={class}
64+
>
65+
<div class={concat!(BASE_CLASS, "-badge__dot")} />
66+
<span>{display_value}</span>
67+
</div>
68+
}
69+
}

crates/leptos/src/button.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use components_core::{BASE_CLASS, concat};
2+
use leptos::prelude::*;
3+
use tailwind_fuse::{AsTailwindClass, TwVariant};
4+
5+
#[derive(TwVariant, PartialEq)]
6+
pub enum Variant {
7+
#[tw(default, class = "rustlanges-button--primary")]
8+
Primary,
9+
#[tw(class = "rustlanges-button--secondary")]
10+
Secondary,
11+
#[tw(class = "rustlanges-button--text")]
12+
Text,
13+
#[tw(class = "rustlanges-button--icon")]
14+
Icon,
15+
}
16+
17+
#[component]
18+
pub fn Button(
19+
#[prop(into, optional)] variant: Variant,
20+
#[prop(into, optional)] label: String,
21+
#[prop(into, optional)] class: String,
22+
#[prop(into)] icon: Option<Children>,
23+
) -> impl IntoView {
24+
let class = crate::tw!(
25+
variant,
26+
concat!("text-button ", BASE_CLASS, "-button"),
27+
class
28+
);
29+
30+
view! {
31+
<button class={class}>
32+
{(variant != Variant::Icon).then_some(label)}
33+
{(variant == Variant::Icon).then(|| icon.map(|icon| icon())).flatten()}
34+
</button>
35+
}
36+
}

crates/leptos/src/card.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use components_core::{BASE_CLASS, concat};
2+
use leptos::prelude::*;
3+
4+
#[component]
5+
pub fn Card(
6+
#[prop(into)] child: Children,
7+
#[prop(into, optional)] class: String,
8+
#[prop(into, optional, default = false)] clickable: bool,
9+
#[prop(into, optional, default = false)] disabled: bool,
10+
) -> impl IntoView {
11+
let class = crate::tw!(
12+
concat!(BASE_CLASS, "-card"),
13+
clickable.then_some(concat!(BASE_CLASS, "-card--clickable")),
14+
disabled.then_some(concat!("disabled ", BASE_CLASS, "-card--disabled")),
15+
class
16+
);
17+
18+
view! {
19+
<div class={class}>
20+
{child()}
21+
</div>
22+
}
23+
}

crates/leptos/src/chip.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use components_core::{BASE_CLASS, concat};
2+
use leptos::prelude::*;
3+
use leptos::{IntoView, component, view};
4+
5+
use crate::icons::{Location, StarBold};
6+
7+
#[derive(Default, Debug, PartialEq)]
8+
pub enum Variant {
9+
#[default]
10+
Featured,
11+
Numeric,
12+
Description,
13+
Location,
14+
Small,
15+
}
16+
17+
impl Variant {
18+
pub fn icon(&self) -> Option<AnyView> {
19+
match self {
20+
Variant::Featured => Some(view! { <StarBold /> }.into_any()),
21+
Variant::Small | Variant::Location => Some(view! { <Location /> }.into_any()),
22+
_ => None,
23+
}
24+
}
25+
}
26+
27+
#[component]
28+
pub fn Chip(
29+
#[prop(into)] label: String,
30+
#[prop(into, optional)] class: String,
31+
#[prop(into, optional)] variant: Variant,
32+
) -> impl IntoView {
33+
let class = crate::tw!(
34+
concat!(BASE_CLASS, "-chip"),
35+
format!("{BASE_CLASS}-chip--{variant:?}"),
36+
class
37+
);
38+
39+
view! {
40+
<div class=class>
41+
{variant.icon()}
42+
{(variant != Variant::Numeric).then_some(format!("#{label}")).unwrap_or(label)}
43+
</div>
44+
}
45+
}

0 commit comments

Comments
 (0)