From d7e1afa5927a27c6d472a4a6128ede24f6ca9162 Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Mon, 23 Jun 2025 01:03:13 -0400 Subject: [PATCH 01/21] feat: add button component --- crates/leptos/src/button.rs | 48 +++++++++++++++++++++++++++++++++++++ crates/leptos/src/lib.rs | 10 ++++---- 2 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 crates/leptos/src/button.rs diff --git a/crates/leptos/src/button.rs b/crates/leptos/src/button.rs new file mode 100644 index 0000000..2088385 --- /dev/null +++ b/crates/leptos/src/button.rs @@ -0,0 +1,48 @@ +use leptos::prelude::{Children, ClassAttribute}; +use leptos::{IntoView, component, view}; +use tailwind_fuse::{AsTailwindClass, TwVariant}; + +#[derive(TwVariant)] +pub enum Variant { + #[default] + #[tw( + default, + class = "border rounded-2xl bg-primary-500 border-black text-black shadow-rb-black dark:bg-primary-300 hover:bg-primary-600 dark:hover:bg-primary-400 active:shadow-none disabled:bg-neutral-100 disabled:shadow-none disabled:border-neutral-400 disabled:text-neutral-400 dark:disabled:bg-neutral-950" + )] + Primary, + #[tw( + class = "border rounded-2xl bg-light text-neutral-950 border-neutral-950 shadow-rb-neutral-950 dark:bg-dark dark:text-light dark:border-light dark:shadow-rb-neutral-50 hover:shadow-rb-primary-500 hover:border-primary-500 hover:text-primary-500 disabled:bg-neutral-100 disabled:text-neutral-400 disabled:border-neutral-400! disabled:shadow-none dark:disabled:bg-neutral-950 active:shadow-none" + )] + Secondary, + #[tw( + class = "text-neutral-950 hover:text-primary-600 dark:text-light dark:hover:text-primary-300" + )] + Text, + #[tw( + class = "rounded-full border aspect-square p-2! !h-fit bg-light border-black text-black dark:bg-dark dark:border-light dark:text-light hover:text-primary-500 hover:border-primary-500" + )] + Icon, +} + +#[component] +pub fn Button( + #[prop(into, optional)] variant: Variant, + #[prop(into, optional)] label: Option, + #[prop(into, optional)] disabled: bool, + #[prop(into, optional)] icon: Children, + #[prop(into, optional)] class: impl AsTailwindClass, +) -> impl IntoView { + let class = crate::tw!( + variant, + "text-button flex h-12 w-fit cursor-pointer items-center justify-center gap-2.5 px-8 transition disabled:cursor-not-allowed", + "[&>svg]:size-6", + class + ); + + view! { + + } +} diff --git a/crates/leptos/src/lib.rs b/crates/leptos/src/lib.rs index dc16173..12407cf 100644 --- a/crates/leptos/src/lib.rs +++ b/crates/leptos/src/lib.rs @@ -1,7 +1,7 @@ -pub use leptos; -use leptos::tachys::renderer::dom::Element; -use leptos::view; +pub(crate) use tailwind_fuse::tw_merge as tw; -fn button() -> Element { - view! {} +pub mod button; + +pub mod prelude { + pub use crate::button::{Button, Variant as ButtonVariant}; } From 14583a4afdeeb1fcbd3331e799feb5a164d0c338 Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Mon, 23 Jun 2025 01:25:48 -0400 Subject: [PATCH 02/21] feat(leptos): add avatar component --- crates/leptos/src/avatar.rs | 22 ++++++++++++++++++++++ crates/leptos/src/lib.rs | 2 ++ 2 files changed, 24 insertions(+) create mode 100644 crates/leptos/src/avatar.rs diff --git a/crates/leptos/src/avatar.rs b/crates/leptos/src/avatar.rs new file mode 100644 index 0000000..0e22407 --- /dev/null +++ b/crates/leptos/src/avatar.rs @@ -0,0 +1,22 @@ +use leptos::prelude::{Children, ClassAttribute}; +use leptos::{IntoView, component, view}; +use tailwind_fuse::{AsTailwindClass, TwVariant}; + +#[component] +pub fn Avatar( + #[prop(into)] url: String, + #[prop(into, optional)] alt: Option, + #[prop(into, optional, default = "32")] size: Option, + #[prop] class: impl AsTailwindClass, +) -> impl IntoView { + let class = crate::tw!( + "grid aspect-square place-items-center overflow-hidden rounded-full border object-cover", + class + ); + + view! { +
+ {alt} +
+ } +} diff --git a/crates/leptos/src/lib.rs b/crates/leptos/src/lib.rs index 12407cf..6cf6c1b 100644 --- a/crates/leptos/src/lib.rs +++ b/crates/leptos/src/lib.rs @@ -1,7 +1,9 @@ pub(crate) use tailwind_fuse::tw_merge as tw; +pub mod avatar; pub mod button; pub mod prelude { + pub use crate::avatar::Avatar; pub use crate::button::{Button, Variant as ButtonVariant}; } From d71e67982d75b790c069942c7c8656f2974bfade Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Mon, 23 Jun 2025 01:34:52 -0400 Subject: [PATCH 03/21] feat(leptos): add tag component --- crates/leptos/src/lib.rs | 2 ++ crates/leptos/src/tag.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 crates/leptos/src/tag.rs diff --git a/crates/leptos/src/lib.rs b/crates/leptos/src/lib.rs index 6cf6c1b..60d9f08 100644 --- a/crates/leptos/src/lib.rs +++ b/crates/leptos/src/lib.rs @@ -2,8 +2,10 @@ pub(crate) use tailwind_fuse::tw_merge as tw; pub mod avatar; pub mod button; +pub mod tag; pub mod prelude { pub use crate::avatar::Avatar; pub use crate::button::{Button, Variant as ButtonVariant}; + pub use crate::tag::Tag; } diff --git a/crates/leptos/src/tag.rs b/crates/leptos/src/tag.rs new file mode 100644 index 0000000..2365438 --- /dev/null +++ b/crates/leptos/src/tag.rs @@ -0,0 +1,26 @@ +use leptos::prelude::{Children, ClassAttribute}; +use leptos::{IntoView, component, view}; +use tailwind_fuse::{AsTailwindClass, TwVariant}; + +#[component] +pub fn Tag( + #[prop(into)] label: String, + #[prop(into, optional)] selected: bool, + #[prop] class: impl AsTailwindClass, +) -> impl IntoView { + let class = crate::tw!( + selected.then_some( + "bg-secondary-100 border-secondary-600 text-secondary-600 dark:bg-primary-950 dark:border-primary-500 dark:text-primary-500", + ).or_else(|| Some( + "bg-light text-black border-black dark:bg-neutral-950 dark:text-neutral-50 dark:border-neutral-50", + )), + "grid h-7 cursor-pointer place-items-center rounded-[20px] border px-2 text-xs font-semibold transition", + class + ); + + view! { +
+ {label} +
+ } +} From 265da1834a5940619e79df0655c4768c1c427f9a Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Mon, 23 Jun 2025 01:38:05 -0400 Subject: [PATCH 04/21] feat(leptos): add radio component --- crates/leptos/src/lib.rs | 7 +++++++ crates/leptos/src/radio.rs | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 crates/leptos/src/radio.rs diff --git a/crates/leptos/src/lib.rs b/crates/leptos/src/lib.rs index 60d9f08..2766802 100644 --- a/crates/leptos/src/lib.rs +++ b/crates/leptos/src/lib.rs @@ -2,10 +2,17 @@ pub(crate) use tailwind_fuse::tw_merge as tw; pub mod avatar; pub mod button; +pub mod radio; pub mod tag; +pub mod inputs { + pub use crate::radio::Radio; +} + pub mod prelude { pub use crate::avatar::Avatar; pub use crate::button::{Button, Variant as ButtonVariant}; pub use crate::tag::Tag; + + pub use crate::radio::Radio as InputRadio; } diff --git a/crates/leptos/src/radio.rs b/crates/leptos/src/radio.rs new file mode 100644 index 0000000..7075f23 --- /dev/null +++ b/crates/leptos/src/radio.rs @@ -0,0 +1,20 @@ +use leptos::prelude::{Children, ClassAttribute}; +use leptos::{IntoView, component, view}; +use tailwind_fuse::{AsTailwindClass, TwVariant}; + +#[component] +pub fn Radio(#[prop] class: impl AsTailwindClass) -> impl IntoView { + let class = crate::tw!( + "shadow-rb-black aspect-square appearance-none transition", + "flex size-4 items-center justify-center rounded-full border border-black", + "after:absolute after:size-2 after:rounded-full after:transition", + "dark:bg-dark bg-white", + "after:bg-gray dark:after:bg-neutral-500", + "checked:after:bg-primary-500", + class + ); + + view! { + + } +} From 2e954f48b01718cdcfb8c8ff01053fcedeb9db67 Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Wed, 9 Jul 2025 01:00:41 -0400 Subject: [PATCH 05/21] feat(leptos): add icons --- crates/leptos/src/icons.rs | 53 ++++++++++++++++++++++++++ crates/leptos/src/icons/alert.rs | 19 +++++++++ crates/leptos/src/icons/arrow_down.rs | 19 +++++++++ crates/leptos/src/icons/arrow_left.rs | 19 +++++++++ crates/leptos/src/icons/arrow_right.rs | 19 +++++++++ crates/leptos/src/icons/arrow_up.rs | 19 +++++++++ crates/leptos/src/icons/book.rs | 19 +++++++++ crates/leptos/src/icons/close.rs | 19 +++++++++ crates/leptos/src/icons/discord.rs | 19 +++++++++ crates/leptos/src/icons/ferris.rs | 19 +++++++++ crates/leptos/src/icons/file.rs | 19 +++++++++ crates/leptos/src/icons/filter.rs | 19 +++++++++ crates/leptos/src/icons/github.rs | 19 +++++++++ crates/leptos/src/icons/link.rs | 19 +++++++++ crates/leptos/src/icons/linkedin.rs | 19 +++++++++ crates/leptos/src/icons/location.rs | 19 +++++++++ crates/leptos/src/icons/menu.rs | 19 +++++++++ crates/leptos/src/icons/moon.rs | 19 +++++++++ crates/leptos/src/icons/project.rs | 19 +++++++++ crates/leptos/src/icons/roadmap.rs | 19 +++++++++ crates/leptos/src/icons/search.rs | 19 +++++++++ crates/leptos/src/icons/share.rs | 19 +++++++++ crates/leptos/src/icons/star_bold.rs | 19 +++++++++ crates/leptos/src/icons/sun_line.rs | 19 +++++++++ crates/leptos/src/icons/telegram.rs | 19 +++++++++ crates/leptos/src/icons/twitter.rs | 19 +++++++++ crates/leptos/src/icons/youtube.rs | 19 +++++++++ crates/leptos/src/lib.rs | 1 + 28 files changed, 548 insertions(+) create mode 100644 crates/leptos/src/icons.rs create mode 100644 crates/leptos/src/icons/alert.rs create mode 100644 crates/leptos/src/icons/arrow_down.rs create mode 100644 crates/leptos/src/icons/arrow_left.rs create mode 100644 crates/leptos/src/icons/arrow_right.rs create mode 100644 crates/leptos/src/icons/arrow_up.rs create mode 100644 crates/leptos/src/icons/book.rs create mode 100644 crates/leptos/src/icons/close.rs create mode 100644 crates/leptos/src/icons/discord.rs create mode 100644 crates/leptos/src/icons/ferris.rs create mode 100644 crates/leptos/src/icons/file.rs create mode 100644 crates/leptos/src/icons/filter.rs create mode 100644 crates/leptos/src/icons/github.rs create mode 100644 crates/leptos/src/icons/link.rs create mode 100644 crates/leptos/src/icons/linkedin.rs create mode 100644 crates/leptos/src/icons/location.rs create mode 100644 crates/leptos/src/icons/menu.rs create mode 100644 crates/leptos/src/icons/moon.rs create mode 100644 crates/leptos/src/icons/project.rs create mode 100644 crates/leptos/src/icons/roadmap.rs create mode 100644 crates/leptos/src/icons/search.rs create mode 100644 crates/leptos/src/icons/share.rs create mode 100644 crates/leptos/src/icons/star_bold.rs create mode 100644 crates/leptos/src/icons/sun_line.rs create mode 100644 crates/leptos/src/icons/telegram.rs create mode 100644 crates/leptos/src/icons/twitter.rs create mode 100644 crates/leptos/src/icons/youtube.rs diff --git a/crates/leptos/src/icons.rs b/crates/leptos/src/icons.rs new file mode 100644 index 0000000..2bd9c8f --- /dev/null +++ b/crates/leptos/src/icons.rs @@ -0,0 +1,53 @@ +mod alert; +mod arrow_down; +mod arrow_left; +mod arrow_right; +mod arrow_up; +mod book; +mod close; +mod discord; +mod ferris; +mod file; +mod filter; +mod github; +mod link; +mod linkedin; +mod location; +mod menu; +mod moon; +mod project; +mod roadmap; +mod search; +mod share; +mod star_bold; +mod sun_line; +mod telegram; +mod twitter; +mod youtube; + +pub use alert::*; +pub use arrow_down::*; +pub use arrow_left::*; +pub use arrow_right::*; +pub use arrow_up::*; +pub use book::*; +pub use close::*; +pub use discord::*; +pub use ferris::*; +pub use file::*; +pub use filter::*; +pub use github::*; +pub use link::*; +pub use linkedin::*; +pub use location::*; +pub use menu::*; +pub use moon::*; +pub use project::*; +pub use roadmap::*; +pub use search::*; +pub use share::*; +pub use star_bold::*; +pub use sun_line::*; +pub use telegram::*; +pub use twitter::*; +pub use youtube::*; diff --git a/crates/leptos/src/icons/alert.rs b/crates/leptos/src/icons/alert.rs new file mode 100644 index 0000000..758fe11 --- /dev/null +++ b/crates/leptos/src/icons/alert.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Alert(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/arrow_down.rs b/crates/leptos/src/icons/arrow_down.rs new file mode 100644 index 0000000..b1f485f --- /dev/null +++ b/crates/leptos/src/icons/arrow_down.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn ArrowDown(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/arrow_left.rs b/crates/leptos/src/icons/arrow_left.rs new file mode 100644 index 0000000..9fcda7e --- /dev/null +++ b/crates/leptos/src/icons/arrow_left.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn ArrowLeft(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/arrow_right.rs b/crates/leptos/src/icons/arrow_right.rs new file mode 100644 index 0000000..e31eaab --- /dev/null +++ b/crates/leptos/src/icons/arrow_right.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn ArrowRight(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/arrow_up.rs b/crates/leptos/src/icons/arrow_up.rs new file mode 100644 index 0000000..8af62bd --- /dev/null +++ b/crates/leptos/src/icons/arrow_up.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn ArrowUp(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/book.rs b/crates/leptos/src/icons/book.rs new file mode 100644 index 0000000..a9cac5d --- /dev/null +++ b/crates/leptos/src/icons/book.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Book(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/close.rs b/crates/leptos/src/icons/close.rs new file mode 100644 index 0000000..a2f7577 --- /dev/null +++ b/crates/leptos/src/icons/close.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Close(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/discord.rs b/crates/leptos/src/icons/discord.rs new file mode 100644 index 0000000..cc7b35d --- /dev/null +++ b/crates/leptos/src/icons/discord.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Discord(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/ferris.rs b/crates/leptos/src/icons/ferris.rs new file mode 100644 index 0000000..becbd7b --- /dev/null +++ b/crates/leptos/src/icons/ferris.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Ferris(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/file.rs b/crates/leptos/src/icons/file.rs new file mode 100644 index 0000000..5083ada --- /dev/null +++ b/crates/leptos/src/icons/file.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn File(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/filter.rs b/crates/leptos/src/icons/filter.rs new file mode 100644 index 0000000..a90ceeb --- /dev/null +++ b/crates/leptos/src/icons/filter.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Filter(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/github.rs b/crates/leptos/src/icons/github.rs new file mode 100644 index 0000000..8c3bb72 --- /dev/null +++ b/crates/leptos/src/icons/github.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Github(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/link.rs b/crates/leptos/src/icons/link.rs new file mode 100644 index 0000000..38b4bda --- /dev/null +++ b/crates/leptos/src/icons/link.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Link(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/linkedin.rs b/crates/leptos/src/icons/linkedin.rs new file mode 100644 index 0000000..4fb5c28 --- /dev/null +++ b/crates/leptos/src/icons/linkedin.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Linkedin(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/location.rs b/crates/leptos/src/icons/location.rs new file mode 100644 index 0000000..a8543f9 --- /dev/null +++ b/crates/leptos/src/icons/location.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Location(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/menu.rs b/crates/leptos/src/icons/menu.rs new file mode 100644 index 0000000..b49e418 --- /dev/null +++ b/crates/leptos/src/icons/menu.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Menu(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/moon.rs b/crates/leptos/src/icons/moon.rs new file mode 100644 index 0000000..11d265b --- /dev/null +++ b/crates/leptos/src/icons/moon.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Moon(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/project.rs b/crates/leptos/src/icons/project.rs new file mode 100644 index 0000000..bb8d78f --- /dev/null +++ b/crates/leptos/src/icons/project.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Project(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/roadmap.rs b/crates/leptos/src/icons/roadmap.rs new file mode 100644 index 0000000..e0cd0bf --- /dev/null +++ b/crates/leptos/src/icons/roadmap.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Roadmap(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/search.rs b/crates/leptos/src/icons/search.rs new file mode 100644 index 0000000..6689165 --- /dev/null +++ b/crates/leptos/src/icons/search.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Search(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/share.rs b/crates/leptos/src/icons/share.rs new file mode 100644 index 0000000..5a9074f --- /dev/null +++ b/crates/leptos/src/icons/share.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Share(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/star_bold.rs b/crates/leptos/src/icons/star_bold.rs new file mode 100644 index 0000000..cf88fb3 --- /dev/null +++ b/crates/leptos/src/icons/star_bold.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn StarBold(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/sun_line.rs b/crates/leptos/src/icons/sun_line.rs new file mode 100644 index 0000000..333cc10 --- /dev/null +++ b/crates/leptos/src/icons/sun_line.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn SunLine(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/telegram.rs b/crates/leptos/src/icons/telegram.rs new file mode 100644 index 0000000..8aba9e8 --- /dev/null +++ b/crates/leptos/src/icons/telegram.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Telegram(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/twitter.rs b/crates/leptos/src/icons/twitter.rs new file mode 100644 index 0000000..fe9d9c9 --- /dev/null +++ b/crates/leptos/src/icons/twitter.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Twitter(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/icons/youtube.rs b/crates/leptos/src/icons/youtube.rs new file mode 100644 index 0000000..e532d33 --- /dev/null +++ b/crates/leptos/src/icons/youtube.rs @@ -0,0 +1,19 @@ +use leptos::{IntoView, component, view}; + +#[component] +fn Youtube(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} diff --git a/crates/leptos/src/lib.rs b/crates/leptos/src/lib.rs index 2766802..9e53bba 100644 --- a/crates/leptos/src/lib.rs +++ b/crates/leptos/src/lib.rs @@ -2,6 +2,7 @@ pub(crate) use tailwind_fuse::tw_merge as tw; pub mod avatar; pub mod button; +pub mod icons; pub mod radio; pub mod tag; From 14cd0929162d5c6de4a8fe84a0079ff257fa148d Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Wed, 9 Jul 2025 01:01:04 -0400 Subject: [PATCH 06/21] feat(leptos): add flaps --- crates/leptos/src/flap.rs | 60 +++++++++++++++++++++++++++++++++++++++ crates/leptos/src/lib.rs | 2 ++ 2 files changed, 62 insertions(+) create mode 100644 crates/leptos/src/flap.rs diff --git a/crates/leptos/src/flap.rs b/crates/leptos/src/flap.rs new file mode 100644 index 0000000..73a52a0 --- /dev/null +++ b/crates/leptos/src/flap.rs @@ -0,0 +1,60 @@ +use leptos::prelude::{Children, ClassAttribute}; +use leptos::{IntoView, component, view}; +use tailwind_fuse::{AsTailwindClass, TwVariant}; + +#[derive(TwVariant)] +pub enum Variant { + #[tw(default, class = "text-primary-400")] + Highlight, + #[tw(class = "text-primary-200")] + Numeric, + #[tw(class = "text-secondary-400")] + Descritive, +} + +#[component] +pub fn Flap( + #[prop(into, optional)] variant: Variant, + #[prop(into)] label: String, + #[prop] class: impl AsTailwindClass, +) -> impl IntoView { + let class = crate::tw!( + "relative flex justify-center gap-2", + "h-6 w-20 px-5", + "desktop:w-[167.5px] desktop:h-[47.5px] desktop:px-8", + class + ); + + view! { +
+ + + + svg]:h-3 [&>svg]:w-3", + )} + > + {(variant == Variant::Highlight).then_some(view! { <> })} + + {label} + + +
+ } +} diff --git a/crates/leptos/src/lib.rs b/crates/leptos/src/lib.rs index 9e53bba..ac994c5 100644 --- a/crates/leptos/src/lib.rs +++ b/crates/leptos/src/lib.rs @@ -2,6 +2,7 @@ pub(crate) use tailwind_fuse::tw_merge as tw; pub mod avatar; pub mod button; +pub mod flap; pub mod icons; pub mod radio; pub mod tag; @@ -13,6 +14,7 @@ pub mod inputs { pub mod prelude { pub use crate::avatar::Avatar; pub use crate::button::{Button, Variant as ButtonVariant}; + pub use crate::flap::Flap; pub use crate::tag::Tag; pub use crate::radio::Radio as InputRadio; From 0ae5f383cd9e6b416bec66b499a1c8e8dababf11 Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Wed, 9 Jul 2025 01:02:07 -0400 Subject: [PATCH 07/21] chore: add simple commit manifest --- sc.toml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 sc.toml diff --git a/sc.toml b/sc.toml new file mode 100644 index 0000000..95e1663 --- /dev/null +++ b/sc.toml @@ -0,0 +1,11 @@ +[git] +skip_preview = true +skip_emojis = true + +[[scopes]] +name = "leptos" +description = "The leptos components related" + +[[scopes]] +name = "react" +description = "The react components related" From e7c5efebe3382a97efe4745cc4f61943374eabdc Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Thu, 10 Jul 2025 20:16:46 -0400 Subject: [PATCH 08/21] chore(rust): create core library to handle common things --- Cargo.lock | 7 +++++++ Cargo.toml | 4 +++- crates/core/Cargo.toml | 7 +++++++ crates/core/src/lib.rs | 3 +++ crates/lib.rs | 2 ++ 5 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 crates/core/Cargo.toml create mode 100644 crates/core/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index e44ab82..66ef85e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -747,6 +747,7 @@ name = "leptos-components" version = "0.1.0" dependencies = [ "leptos", + "rustlanges-components-core", "tailwind_fuse", ] @@ -1271,6 +1272,12 @@ name = "rustlanges-components" version = "0.1.0" dependencies = [ "leptos-components", + +[[package]] +name = "rustlanges-components-core" +version = "0.1.0" +dependencies = [ + "constcat", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 285552d..e81cf96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "rustlanges-components" version = "0.1.0" +edition = "2024" [lib] path = "crates/lib.rs" @@ -9,7 +10,8 @@ path = "crates/lib.rs" leptos = ["leptos-components"] [workspace] -members = ["crates/leptos"] +members = [ "crates/core", "crates/leptos" ] [dependencies] +components-core = { package = "rustlanges-components-core", version = "0.1.0", path = "./crates/core" } leptos-components = { path = "./crates/leptos", optional = true } diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml new file mode 100644 index 0000000..097e2a9 --- /dev/null +++ b/crates/core/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "rustlanges-components-core" +version = "0.1.0" +edition = "2024" + +[dependencies] +constcat = "0.6.1" diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs new file mode 100644 index 0000000..23afd7d --- /dev/null +++ b/crates/core/src/lib.rs @@ -0,0 +1,3 @@ +pub const BASE_CLASS: &str = "rustlanges"; + +pub use constcat::{concat, concat_bytes, concat_slices}; diff --git a/crates/lib.rs b/crates/lib.rs index 01eb157..85f6059 100644 --- a/crates/lib.rs +++ b/crates/lib.rs @@ -1,2 +1,4 @@ +pub use components_core::*; + #[cfg(feature = "leptos")] pub use leptos_components::*; From 8a63816ceec3cdf8264f9f80d55302a871a658d6 Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Fri, 11 Jul 2025 20:17:59 -0400 Subject: [PATCH 09/21] fix(leptos): update icons to compile --- crates/leptos/src/icons/alert.rs | 2 +- crates/leptos/src/icons/arrow_down.rs | 2 +- crates/leptos/src/icons/arrow_left.rs | 2 +- crates/leptos/src/icons/arrow_right.rs | 2 +- crates/leptos/src/icons/arrow_up.rs | 2 +- crates/leptos/src/icons/book.rs | 2 +- crates/leptos/src/icons/close.rs | 2 +- crates/leptos/src/icons/discord.rs | 2 +- crates/leptos/src/icons/ferris.rs | 2 +- crates/leptos/src/icons/file.rs | 2 +- crates/leptos/src/icons/filter.rs | 2 +- crates/leptos/src/icons/github.rs | 2 +- crates/leptos/src/icons/link.rs | 2 +- crates/leptos/src/icons/linkedin.rs | 2 +- crates/leptos/src/icons/location.rs | 2 +- crates/leptos/src/icons/menu.rs | 2 +- crates/leptos/src/icons/moon.rs | 2 +- crates/leptos/src/icons/project.rs | 2 +- crates/leptos/src/icons/roadmap.rs | 2 +- crates/leptos/src/icons/search.rs | 2 +- crates/leptos/src/icons/share.rs | 2 +- crates/leptos/src/icons/star_bold.rs | 2 +- crates/leptos/src/icons/sun_line.rs | 2 +- crates/leptos/src/icons/telegram.rs | 2 +- crates/leptos/src/icons/twitter.rs | 2 +- crates/leptos/src/icons/youtube.rs | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/crates/leptos/src/icons/alert.rs b/crates/leptos/src/icons/alert.rs index 758fe11..d4587f2 100644 --- a/crates/leptos/src/icons/alert.rs +++ b/crates/leptos/src/icons/alert.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Alert(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/arrow_down.rs b/crates/leptos/src/icons/arrow_down.rs index b1f485f..92b8a3f 100644 --- a/crates/leptos/src/icons/arrow_down.rs +++ b/crates/leptos/src/icons/arrow_down.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn ArrowDown(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/arrow_left.rs b/crates/leptos/src/icons/arrow_left.rs index 9fcda7e..c485162 100644 --- a/crates/leptos/src/icons/arrow_left.rs +++ b/crates/leptos/src/icons/arrow_left.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn ArrowLeft(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/arrow_right.rs b/crates/leptos/src/icons/arrow_right.rs index e31eaab..1aad722 100644 --- a/crates/leptos/src/icons/arrow_right.rs +++ b/crates/leptos/src/icons/arrow_right.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn ArrowRight(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/arrow_up.rs b/crates/leptos/src/icons/arrow_up.rs index 8af62bd..e3f1c05 100644 --- a/crates/leptos/src/icons/arrow_up.rs +++ b/crates/leptos/src/icons/arrow_up.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn ArrowUp(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/book.rs b/crates/leptos/src/icons/book.rs index a9cac5d..92ccfd2 100644 --- a/crates/leptos/src/icons/book.rs +++ b/crates/leptos/src/icons/book.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Book(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/close.rs b/crates/leptos/src/icons/close.rs index a2f7577..0e3c453 100644 --- a/crates/leptos/src/icons/close.rs +++ b/crates/leptos/src/icons/close.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Close(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/discord.rs b/crates/leptos/src/icons/discord.rs index cc7b35d..e5f3637 100644 --- a/crates/leptos/src/icons/discord.rs +++ b/crates/leptos/src/icons/discord.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Discord(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/ferris.rs b/crates/leptos/src/icons/ferris.rs index becbd7b..f7d5084 100644 --- a/crates/leptos/src/icons/ferris.rs +++ b/crates/leptos/src/icons/ferris.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Ferris(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/file.rs b/crates/leptos/src/icons/file.rs index 5083ada..c304d94 100644 --- a/crates/leptos/src/icons/file.rs +++ b/crates/leptos/src/icons/file.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn File(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/filter.rs b/crates/leptos/src/icons/filter.rs index a90ceeb..dab314d 100644 --- a/crates/leptos/src/icons/filter.rs +++ b/crates/leptos/src/icons/filter.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Filter(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/github.rs b/crates/leptos/src/icons/github.rs index 8c3bb72..0d0d76f 100644 --- a/crates/leptos/src/icons/github.rs +++ b/crates/leptos/src/icons/github.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Github(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/link.rs b/crates/leptos/src/icons/link.rs index 38b4bda..27d716c 100644 --- a/crates/leptos/src/icons/link.rs +++ b/crates/leptos/src/icons/link.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Link(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/linkedin.rs b/crates/leptos/src/icons/linkedin.rs index 4fb5c28..345bdea 100644 --- a/crates/leptos/src/icons/linkedin.rs +++ b/crates/leptos/src/icons/linkedin.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Linkedin(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/location.rs b/crates/leptos/src/icons/location.rs index a8543f9..c65194f 100644 --- a/crates/leptos/src/icons/location.rs +++ b/crates/leptos/src/icons/location.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Location(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/menu.rs b/crates/leptos/src/icons/menu.rs index b49e418..4fff272 100644 --- a/crates/leptos/src/icons/menu.rs +++ b/crates/leptos/src/icons/menu.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Menu(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/moon.rs b/crates/leptos/src/icons/moon.rs index 11d265b..f3c2523 100644 --- a/crates/leptos/src/icons/moon.rs +++ b/crates/leptos/src/icons/moon.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Moon(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/project.rs b/crates/leptos/src/icons/project.rs index bb8d78f..bb43220 100644 --- a/crates/leptos/src/icons/project.rs +++ b/crates/leptos/src/icons/project.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Project(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/roadmap.rs b/crates/leptos/src/icons/roadmap.rs index e0cd0bf..674c35b 100644 --- a/crates/leptos/src/icons/roadmap.rs +++ b/crates/leptos/src/icons/roadmap.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Roadmap(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/search.rs b/crates/leptos/src/icons/search.rs index 6689165..6e225d8 100644 --- a/crates/leptos/src/icons/search.rs +++ b/crates/leptos/src/icons/search.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Search(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/share.rs b/crates/leptos/src/icons/share.rs index 5a9074f..69d51e1 100644 --- a/crates/leptos/src/icons/share.rs +++ b/crates/leptos/src/icons/share.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Share(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/star_bold.rs b/crates/leptos/src/icons/star_bold.rs index cf88fb3..8bd4982 100644 --- a/crates/leptos/src/icons/star_bold.rs +++ b/crates/leptos/src/icons/star_bold.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn StarBold(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/sun_line.rs b/crates/leptos/src/icons/sun_line.rs index 333cc10..5657a13 100644 --- a/crates/leptos/src/icons/sun_line.rs +++ b/crates/leptos/src/icons/sun_line.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn SunLine(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/telegram.rs b/crates/leptos/src/icons/telegram.rs index 8aba9e8..d3b6357 100644 --- a/crates/leptos/src/icons/telegram.rs +++ b/crates/leptos/src/icons/telegram.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Telegram(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/twitter.rs b/crates/leptos/src/icons/twitter.rs index fe9d9c9..7856d5a 100644 --- a/crates/leptos/src/icons/twitter.rs +++ b/crates/leptos/src/icons/twitter.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Twitter(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { diff --git a/crates/leptos/src/icons/youtube.rs b/crates/leptos/src/icons/youtube.rs index e532d33..2d80aeb 100644 --- a/crates/leptos/src/icons/youtube.rs +++ b/crates/leptos/src/icons/youtube.rs @@ -1,4 +1,4 @@ -use leptos::{IntoView, component, view}; +use leptos::prelude::*; #[component] fn Youtube(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { From c0b4bb499d3bd50e215e708b83e04bc6eddfc3ac Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Sat, 12 Jul 2025 20:27:35 -0400 Subject: [PATCH 10/21] feat(rust): script to generate icons from react --- icons-from-react.nu | 61 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 icons-from-react.nu diff --git a/icons-from-react.nu b/icons-from-react.nu new file mode 100644 index 0000000..873a544 --- /dev/null +++ b/icons-from-react.nu @@ -0,0 +1,61 @@ +def main [ + --rust (-r) + outDir: path = crates/leptos/src/icons +] { + mkdir crates/leptos/src/icons + + let files = ls -a -f js/react/lib/icons/*.tsx | get name + + let mod_content = $files | each {|file| + let name = ($file | path basename | str replace ".tsx" "") | str snake-case + + if $rust { $"mod ($name);" } else { "" } + } | str join "\n" + + let use_content = $files | each {|file| + let name = ($file | path basename | str replace ".tsx" "") | str snake-case + + if $rust { $"pub use ($name)::*;" } else { "" } + } | str join "\n" + + + $"($mod_content)\n\n($use_content)\n" | save -f $"($outDir).rs" + + $files | each { |file| + let name = ($file | path basename | str replace ".tsx" "") + + let dest_path = $"($outDir)/($name | str snake-case).rs" + let name = $name | str pascal-case + + let content = open $file + + let svg_attrs = ($content | split row "" | get 0) + let path_data = ($content | split row 'd="' | get 1 | split row '"' | get 0) + + let rust_content = r#'use leptos::prelude::*; + +#[component] +fn $name(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { + view! { + + + + } +} +'# + + if $rust { + $rust_content | str replace "\$name" $name | str replace "\$path_data" $path_data | save -f $dest_path + echo $"Convertido ($name).tsx a ($dest_path)" + } + } +} From 7779522832211b467284804385fab3bf95cb58bf Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Sat, 12 Jul 2025 20:28:54 -0400 Subject: [PATCH 11/21] chore: update simple commit manifest --- sc.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sc.toml b/sc.toml index 95e1663..86bb695 100644 --- a/sc.toml +++ b/sc.toml @@ -2,6 +2,10 @@ skip_preview = true skip_emojis = true +[[scopes]] +name = "rust" +description = "The rust core library related" + [[scopes]] name = "leptos" description = "The leptos components related" From 7d9ed70bb905ee696f17d5f437f5909f2be116ad Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Sun, 13 Jul 2025 20:48:59 -0400 Subject: [PATCH 12/21] refactor(leptos): migrate to rustlang-es standard class name --- Cargo.lock | 8 ++++++ crates/leptos/Cargo.toml | 1 + crates/leptos/src/avatar.rs | 22 +++++++------- crates/leptos/src/button.rs | 38 +++++++++---------------- crates/leptos/src/flap.rs | 57 ++++++++++++++++--------------------- crates/leptos/src/radio.rs | 16 +++-------- crates/leptos/src/tag.rs | 16 +++++------ 7 files changed, 68 insertions(+), 90 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66ef85e..b92498c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -193,6 +193,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f67855af358fcb20fac58f9d714c94e2b228fe5694c1c9b4ead4a366343eda1b" +[[package]] +name = "constcat" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d3e02915a2cea4d74caa8681e2d44b1c3254bdbf17d11d41d587ff858832c" + [[package]] name = "convert_case" version = "0.6.0" @@ -1272,6 +1278,8 @@ name = "rustlanges-components" version = "0.1.0" dependencies = [ "leptos-components", + "rustlanges-components-core", +] [[package]] name = "rustlanges-components-core" diff --git a/crates/leptos/Cargo.toml b/crates/leptos/Cargo.toml index a7159f4..f8f7ca6 100644 --- a/crates/leptos/Cargo.toml +++ b/crates/leptos/Cargo.toml @@ -5,4 +5,5 @@ edition = "2024" [dependencies] leptos = { version = "0.8.2", default-features = false } +components-core = { package = "rustlanges-components-core", version = "0.1.0", path = "../core" } tailwind_fuse = { version = "0.3", features = ["variant", "tailwind_fuse_macro"] } diff --git a/crates/leptos/src/avatar.rs b/crates/leptos/src/avatar.rs index 0e22407..8be3e49 100644 --- a/crates/leptos/src/avatar.rs +++ b/crates/leptos/src/avatar.rs @@ -1,22 +1,22 @@ -use leptos::prelude::{Children, ClassAttribute}; -use leptos::{IntoView, component, view}; -use tailwind_fuse::{AsTailwindClass, TwVariant}; +use components_core::{BASE_CLASS, concat}; +use leptos::prelude::*; #[component] pub fn Avatar( #[prop(into)] url: String, #[prop(into, optional)] alt: Option, - #[prop(into, optional, default = "32")] size: Option, - #[prop] class: impl AsTailwindClass, + #[prop(into, optional, default = Some(32))] size: Option, + #[prop(into, optional)] class: String, ) -> impl IntoView { - let class = crate::tw!( - "grid aspect-square place-items-center overflow-hidden rounded-full border object-cover", - class - ); + let class = crate::tw!(concat!(BASE_CLASS, "-avatar"), class); view! { -
- {alt} +
+ {alt}
} } diff --git a/crates/leptos/src/button.rs b/crates/leptos/src/button.rs index 2088385..fea7592 100644 --- a/crates/leptos/src/button.rs +++ b/crates/leptos/src/button.rs @@ -1,48 +1,36 @@ -use leptos::prelude::{Children, ClassAttribute}; -use leptos::{IntoView, component, view}; +use components_core::{BASE_CLASS, concat}; +use leptos::prelude::*; use tailwind_fuse::{AsTailwindClass, TwVariant}; -#[derive(TwVariant)] +#[derive(TwVariant, PartialEq)] pub enum Variant { - #[default] - #[tw( - default, - class = "border rounded-2xl bg-primary-500 border-black text-black shadow-rb-black dark:bg-primary-300 hover:bg-primary-600 dark:hover:bg-primary-400 active:shadow-none disabled:bg-neutral-100 disabled:shadow-none disabled:border-neutral-400 disabled:text-neutral-400 dark:disabled:bg-neutral-950" - )] + #[tw(default, class = "rustlanges-button--primary")] Primary, - #[tw( - class = "border rounded-2xl bg-light text-neutral-950 border-neutral-950 shadow-rb-neutral-950 dark:bg-dark dark:text-light dark:border-light dark:shadow-rb-neutral-50 hover:shadow-rb-primary-500 hover:border-primary-500 hover:text-primary-500 disabled:bg-neutral-100 disabled:text-neutral-400 disabled:border-neutral-400! disabled:shadow-none dark:disabled:bg-neutral-950 active:shadow-none" - )] + #[tw(class = "rustlanges-button--secondary")] Secondary, - #[tw( - class = "text-neutral-950 hover:text-primary-600 dark:text-light dark:hover:text-primary-300" - )] + #[tw(class = "rustlanges-button--text")] Text, - #[tw( - class = "rounded-full border aspect-square p-2! !h-fit bg-light border-black text-black dark:bg-dark dark:border-light dark:text-light hover:text-primary-500 hover:border-primary-500" - )] + #[tw(class = "rustlanges-button--icon")] Icon, } #[component] pub fn Button( #[prop(into, optional)] variant: Variant, - #[prop(into, optional)] label: Option, - #[prop(into, optional)] disabled: bool, - #[prop(into, optional)] icon: Children, - #[prop(into, optional)] class: impl AsTailwindClass, + #[prop(into, optional)] label: String, + #[prop(into, optional)] class: String, + #[prop(into)] icon: Option, ) -> impl IntoView { let class = crate::tw!( variant, - "text-button flex h-12 w-fit cursor-pointer items-center justify-center gap-2.5 px-8 transition disabled:cursor-not-allowed", - "[&>svg]:size-6", + concat!("text-button ", BASE_CLASS, "-button"), class ); view! { } } diff --git a/crates/leptos/src/flap.rs b/crates/leptos/src/flap.rs index 73a52a0..e4f6e72 100644 --- a/crates/leptos/src/flap.rs +++ b/crates/leptos/src/flap.rs @@ -1,8 +1,9 @@ -use leptos::prelude::{Children, ClassAttribute}; +use components_core::{BASE_CLASS, concat}; +use leptos::prelude::*; use leptos::{IntoView, component, view}; use tailwind_fuse::{AsTailwindClass, TwVariant}; -#[derive(TwVariant)] +#[derive(TwVariant, PartialEq)] pub enum Variant { #[tw(default, class = "text-primary-400")] Highlight, @@ -14,46 +15,36 @@ pub enum Variant { #[component] pub fn Flap( - #[prop(into, optional)] variant: Variant, #[prop(into)] label: String, - #[prop] class: impl AsTailwindClass, + #[prop(into, optional)] variant: Variant, + #[prop(into, optional)] class: String, ) -> impl IntoView { - let class = crate::tw!( - "relative flex justify-center gap-2", - "h-6 w-20 px-5", - "desktop:w-[167.5px] desktop:h-[47.5px] desktop:px-8", - class - ); + let class = crate::tw!(concat!(BASE_CLASS, "-flap"), class); view! { -
+
- + svg]:h-3 [&>svg]:w-3", - )} + class={crate::tw!( + concat!(BASE_CLASS, "-flap__view"), + (variant == Variant::Highlight).then_some(concat!(BASE_CLASS, "-flap__view--icon")), + )} > - {(variant == Variant::Highlight).then_some(view! { <> })} - - {label} - + {(variant == Variant::Highlight).then_some(view! { <> })} + + {label.clone()} +
} diff --git a/crates/leptos/src/radio.rs b/crates/leptos/src/radio.rs index 7075f23..9e0c0c1 100644 --- a/crates/leptos/src/radio.rs +++ b/crates/leptos/src/radio.rs @@ -1,18 +1,10 @@ -use leptos::prelude::{Children, ClassAttribute}; +use components_core::{BASE_CLASS, concat}; +use leptos::prelude::ClassAttribute; use leptos::{IntoView, component, view}; -use tailwind_fuse::{AsTailwindClass, TwVariant}; #[component] -pub fn Radio(#[prop] class: impl AsTailwindClass) -> impl IntoView { - let class = crate::tw!( - "shadow-rb-black aspect-square appearance-none transition", - "flex size-4 items-center justify-center rounded-full border border-black", - "after:absolute after:size-2 after:rounded-full after:transition", - "dark:bg-dark bg-white", - "after:bg-gray dark:after:bg-neutral-500", - "checked:after:bg-primary-500", - class - ); +pub fn Radio(#[prop(into, optional)] class: String) -> impl IntoView { + let class = crate::tw!(concat!(BASE_CLASS, "-radio"), class); view! { diff --git a/crates/leptos/src/tag.rs b/crates/leptos/src/tag.rs index 2365438..2aea522 100644 --- a/crates/leptos/src/tag.rs +++ b/crates/leptos/src/tag.rs @@ -1,20 +1,18 @@ -use leptos::prelude::{Children, ClassAttribute}; +use components_core::{BASE_CLASS, concat}; +use leptos::prelude::*; use leptos::{IntoView, component, view}; -use tailwind_fuse::{AsTailwindClass, TwVariant}; #[component] pub fn Tag( #[prop(into)] label: String, #[prop(into, optional)] selected: bool, - #[prop] class: impl AsTailwindClass, + #[prop(into, optional)] class: String, ) -> impl IntoView { let class = crate::tw!( - selected.then_some( - "bg-secondary-100 border-secondary-600 text-secondary-600 dark:bg-primary-950 dark:border-primary-500 dark:text-primary-500", - ).or_else(|| Some( - "bg-light text-black border-black dark:bg-neutral-950 dark:text-neutral-50 dark:border-neutral-50", - )), - "grid h-7 cursor-pointer place-items-center rounded-[20px] border px-2 text-xs font-semibold transition", + selected + .then_some(concat!(BASE_CLASS, "-tag--selected"),) + .or_else(|| Some(concat!(BASE_CLASS, "-tag--default"),)), + concat!(BASE_CLASS, "-tag"), class ); From 306712b20686e20aa3fbc1642740c9db1f17a797 Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Sun, 13 Jul 2025 21:36:05 -0400 Subject: [PATCH 13/21] feat(leptos): add badge component --- crates/leptos/src/badge.rs | 69 ++++++++++++++++++++++++++++++++++++++ crates/leptos/src/lib.rs | 2 ++ 2 files changed, 71 insertions(+) create mode 100644 crates/leptos/src/badge.rs diff --git a/crates/leptos/src/badge.rs b/crates/leptos/src/badge.rs new file mode 100644 index 0000000..9d098e3 --- /dev/null +++ b/crates/leptos/src/badge.rs @@ -0,0 +1,69 @@ +use components_core::{BASE_CLASS, concat}; +use leptos::prelude::*; +use leptos::{IntoView, component, view}; + +const LIMIT_NUMERIC: isize = 9; +const LIMIT_NUMERIC_NEGATIVE: isize = -9; + +#[derive(Default, Debug, PartialEq)] +pub enum Variant { + Completed, + Reading, + #[default] + Pending, + Unread, +} + +impl Variant { + pub fn text(&self) -> &'static str { + match self { + Variant::Completed => "Completo", + Variant::Reading => "Leyendo", + Variant::Pending => "Pendiente", + Variant::Unread => "No leido", + } + } +} + +#[derive(Default, Debug, PartialEq)] +pub enum Type { + #[default] + Default, + Numeric, + Text, +} + +#[component] +pub fn Badge( + #[prop(into)] count: ReadSignal, + #[prop(into, optional)] variant: Variant, + #[prop(into, optional)] r#type: Type, +) -> impl IntoView { + let class = crate::tw!( + concat!("text-paragraph-2 ", BASE_CLASS, "-badge"), + format!("{BASE_CLASS}-badge--variant-{variant:?}"), + format!("{BASE_CLASS}-badge--type-{type:?}"), + ); + + let display_value = move || match r#type { + Type::Default => count.get().to_string(), + Type::Numeric => { + let count = count.get(); + match count { + ..=LIMIT_NUMERIC_NEGATIVE => LIMIT_NUMERIC_NEGATIVE.to_string(), + LIMIT_NUMERIC.. => format!("+{LIMIT_NUMERIC}"), + _ => count.to_string(), + } + } + Type::Text => variant.text().to_string(), + }; + + view! { +
+
+ {display_value} +
+ } +} diff --git a/crates/leptos/src/lib.rs b/crates/leptos/src/lib.rs index ac994c5..5e09ae4 100644 --- a/crates/leptos/src/lib.rs +++ b/crates/leptos/src/lib.rs @@ -1,6 +1,7 @@ pub(crate) use tailwind_fuse::tw_merge as tw; pub mod avatar; +pub mod badge; pub mod button; pub mod flap; pub mod icons; @@ -13,6 +14,7 @@ pub mod inputs { pub mod prelude { pub use crate::avatar::Avatar; + pub use crate::badge::{Badge, Type as BadgeType, Variant as BadgeVariant}; pub use crate::button::{Button, Variant as ButtonVariant}; pub use crate::flap::Flap; pub use crate::tag::Tag; From f3ac40115ac1c011edb2f8ea6a63f315d36229ba Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Sun, 13 Jul 2025 22:30:41 -0400 Subject: [PATCH 14/21] feat(leptos): add card component --- crates/leptos/src/card.rs | 23 +++++++++++++++++++++++ crates/leptos/src/lib.rs | 2 ++ 2 files changed, 25 insertions(+) create mode 100644 crates/leptos/src/card.rs diff --git a/crates/leptos/src/card.rs b/crates/leptos/src/card.rs new file mode 100644 index 0000000..95d0eb4 --- /dev/null +++ b/crates/leptos/src/card.rs @@ -0,0 +1,23 @@ +use components_core::{BASE_CLASS, concat}; +use leptos::prelude::*; + +#[component] +pub fn Card( + #[prop(into)] child: Children, + #[prop(into, optional)] class: String, + #[prop(into, optional, default = false)] clickable: bool, + #[prop(into, optional, default = false)] disabled: bool, +) -> impl IntoView { + let class = crate::tw!( + concat!(BASE_CLASS, "-card"), + clickable.then_some(concat!(BASE_CLASS, "-card--clickable")), + disabled.then_some(concat!("disabled ", BASE_CLASS, "-card--disabled")), + class + ); + + view! { +
+ {child()} +
+ } +} diff --git a/crates/leptos/src/lib.rs b/crates/leptos/src/lib.rs index 5e09ae4..9c1a61f 100644 --- a/crates/leptos/src/lib.rs +++ b/crates/leptos/src/lib.rs @@ -3,6 +3,7 @@ pub(crate) use tailwind_fuse::tw_merge as tw; pub mod avatar; pub mod badge; pub mod button; +pub mod card; pub mod flap; pub mod icons; pub mod radio; @@ -16,6 +17,7 @@ pub mod prelude { pub use crate::avatar::Avatar; pub use crate::badge::{Badge, Type as BadgeType, Variant as BadgeVariant}; pub use crate::button::{Button, Variant as ButtonVariant}; + pub use crate::card::Card; pub use crate::flap::Flap; pub use crate::tag::Tag; From e5d2ebc0160b08eeb611bab5ec451bab136de693 Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Sun, 13 Jul 2025 22:59:36 -0400 Subject: [PATCH 15/21] feat(leptos): add progress bar component --- crates/leptos/src/lib.rs | 2 ++ crates/leptos/src/progress_bar.rs | 49 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 crates/leptos/src/progress_bar.rs diff --git a/crates/leptos/src/lib.rs b/crates/leptos/src/lib.rs index 9c1a61f..94ccbae 100644 --- a/crates/leptos/src/lib.rs +++ b/crates/leptos/src/lib.rs @@ -6,6 +6,7 @@ pub mod button; pub mod card; pub mod flap; pub mod icons; +pub mod progress_bar; pub mod radio; pub mod tag; @@ -19,6 +20,7 @@ pub mod prelude { pub use crate::button::{Button, Variant as ButtonVariant}; pub use crate::card::Card; pub use crate::flap::Flap; + pub use crate::progress_bar::ProgressBar; pub use crate::tag::Tag; pub use crate::radio::Radio as InputRadio; diff --git a/crates/leptos/src/progress_bar.rs b/crates/leptos/src/progress_bar.rs new file mode 100644 index 0000000..347166d --- /dev/null +++ b/crates/leptos/src/progress_bar.rs @@ -0,0 +1,49 @@ +use components_core::concat; +use leptos::prelude::*; +use leptos::{IntoView, component, view}; + +use crate::icons::Ferris; + +const BASE_CLASS: &str = concat!(components_core::BASE_CLASS, "-progress-bar"); + +#[component] +pub fn ProgressBar(#[prop(into)] percentage: ReadSignal) -> impl IntoView { + let percentage = percentage.get(); + let progress_in_limit = percentage == 0 || percentage == 100; + let progress_in_min_limit = percentage < 25; + + let min_limit_class = crate::tw!( + concat!("text-overline ", BASE_CLASS, "__percentage"), + progress_in_min_limit.then_some(concat!( + "text-overline ", + BASE_CLASS, + "__percentage--invert" + )) + ); + + let max_limit_class = crate::tw!( + concat!(BASE_CLASS, "__fill"), + progress_in_limit.then_some(concat!(BASE_CLASS, "__fill--limit")) + ); + + let percentage_str = format!("{percentage}%"); + + view! { +
+
+ + {percentage_str.clone()} + + +
+
+
+ } +} From b88a25c84ad14766c6c025cfa70b28efe69a0a2b Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Sun, 13 Jul 2025 23:01:50 -0400 Subject: [PATCH 16/21] fix(leptos): icons components --- crates/leptos/src/icons.rs | 52 +++++++++++++------------- crates/leptos/src/icons/alert.rs | 2 +- crates/leptos/src/icons/arrow_down.rs | 2 +- crates/leptos/src/icons/arrow_left.rs | 2 +- crates/leptos/src/icons/arrow_right.rs | 2 +- crates/leptos/src/icons/arrow_up.rs | 2 +- crates/leptos/src/icons/book.rs | 2 +- crates/leptos/src/icons/close.rs | 2 +- crates/leptos/src/icons/discord.rs | 2 +- crates/leptos/src/icons/ferris.rs | 2 +- crates/leptos/src/icons/file.rs | 2 +- crates/leptos/src/icons/filter.rs | 2 +- crates/leptos/src/icons/github.rs | 2 +- crates/leptos/src/icons/link.rs | 2 +- crates/leptos/src/icons/linkedin.rs | 2 +- crates/leptos/src/icons/location.rs | 2 +- crates/leptos/src/icons/menu.rs | 2 +- crates/leptos/src/icons/moon.rs | 2 +- crates/leptos/src/icons/project.rs | 2 +- crates/leptos/src/icons/roadmap.rs | 2 +- crates/leptos/src/icons/search.rs | 2 +- crates/leptos/src/icons/share.rs | 2 +- crates/leptos/src/icons/star_bold.rs | 2 +- crates/leptos/src/icons/sun_line.rs | 2 +- crates/leptos/src/icons/telegram.rs | 2 +- crates/leptos/src/icons/twitter.rs | 2 +- crates/leptos/src/icons/youtube.rs | 2 +- icons-from-react.nu | 6 +-- 28 files changed, 55 insertions(+), 55 deletions(-) diff --git a/crates/leptos/src/icons.rs b/crates/leptos/src/icons.rs index 2bd9c8f..0e3f586 100644 --- a/crates/leptos/src/icons.rs +++ b/crates/leptos/src/icons.rs @@ -25,29 +25,29 @@ mod telegram; mod twitter; mod youtube; -pub use alert::*; -pub use arrow_down::*; -pub use arrow_left::*; -pub use arrow_right::*; -pub use arrow_up::*; -pub use book::*; -pub use close::*; -pub use discord::*; -pub use ferris::*; -pub use file::*; -pub use filter::*; -pub use github::*; -pub use link::*; -pub use linkedin::*; -pub use location::*; -pub use menu::*; -pub use moon::*; -pub use project::*; -pub use roadmap::*; -pub use search::*; -pub use share::*; -pub use star_bold::*; -pub use sun_line::*; -pub use telegram::*; -pub use twitter::*; -pub use youtube::*; +pub use alert::Alert; +pub use arrow_down::ArrowDown; +pub use arrow_left::ArrowLeft; +pub use arrow_right::ArrowRight; +pub use arrow_up::ArrowUp; +pub use book::Book; +pub use close::Close; +pub use discord::Discord; +pub use ferris::Ferris; +pub use file::File; +pub use filter::Filter; +pub use github::Github; +pub use link::Link; +pub use linkedin::Linkedin; +pub use location::Location; +pub use menu::Menu; +pub use moon::Moon; +pub use project::Project; +pub use roadmap::Roadmap; +pub use search::Search; +pub use share::Share; +pub use star_bold::StarBold; +pub use sun_line::SunLine; +pub use telegram::Telegram; +pub use twitter::Twitter; +pub use youtube::Youtube; diff --git a/crates/leptos/src/icons/alert.rs b/crates/leptos/src/icons/alert.rs index d4587f2..3817064 100644 --- a/crates/leptos/src/icons/alert.rs +++ b/crates/leptos/src/icons/alert.rs @@ -1,7 +1,7 @@ use leptos::prelude::*; #[component] -fn Alert(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { +pub fn Alert(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn ArrowDown(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn ArrowLeft(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn ArrowRight(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn ArrowUp(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Book(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Close(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Discord(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Ferris(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn File(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Filter(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Github(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Link(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Linkedin(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Location(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Menu(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Moon(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Project(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Roadmap(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Search(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Share(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn StarBold(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn SunLine(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Telegram(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Twitter(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn Youtube(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { impl IntoView { +pub fn $name(#[prop(into, optional, default = 24)] size: u32) -> impl IntoView { view! { Date: Sun, 13 Jul 2025 23:13:47 -0400 Subject: [PATCH 17/21] feat(leptos): add level component --- crates/leptos/src/level.rs | 42 ++++++++++++++++++++++++++++++++++++++ crates/leptos/src/lib.rs | 2 ++ 2 files changed, 44 insertions(+) create mode 100644 crates/leptos/src/level.rs diff --git a/crates/leptos/src/level.rs b/crates/leptos/src/level.rs new file mode 100644 index 0000000..cd44329 --- /dev/null +++ b/crates/leptos/src/level.rs @@ -0,0 +1,42 @@ +use components_core::{BASE_CLASS, concat}; +use leptos::prelude::*; +use leptos::{IntoView, component, view}; + +#[derive(Default, Debug, PartialEq)] +pub enum Variant { + #[default] + N1, + N2, + N3, + OP, +} + +impl ToString for Variant { + fn to_string(&self) -> String { + match self { + Variant::N1 => "N1".into(), + Variant::N2 => "N2".into(), + Variant::N3 => "N3".into(), + Variant::OP => "Op".into(), + } + } +} + +#[component] +pub fn Level( + #[prop(into, optional)] variant: Variant, + #[prop(into, optional)] class: String, +) -> impl IntoView { + let variant = variant.to_string(); + let class = crate::tw!( + concat!(BASE_CLASS, "-level"), + format!("{BASE_CLASS}-level--{}", variant.to_lowercase()), + class + ); + + view! { +
+ {variant} +
+ } +} diff --git a/crates/leptos/src/lib.rs b/crates/leptos/src/lib.rs index 94ccbae..eea841f 100644 --- a/crates/leptos/src/lib.rs +++ b/crates/leptos/src/lib.rs @@ -6,6 +6,7 @@ pub mod button; pub mod card; pub mod flap; pub mod icons; +pub mod level; pub mod progress_bar; pub mod radio; pub mod tag; @@ -20,6 +21,7 @@ pub mod prelude { pub use crate::button::{Button, Variant as ButtonVariant}; pub use crate::card::Card; pub use crate::flap::Flap; + pub use crate::level::{Level, Variant as LevelVariant}; pub use crate::progress_bar::ProgressBar; pub use crate::tag::Tag; From 4b0bd5e198bab5d0b49280c014c39d46936ed2e2 Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Sun, 13 Jul 2025 23:52:09 -0400 Subject: [PATCH 18/21] feat(leptos): add chip component --- crates/leptos/src/chip.rs | 45 +++++++++++++++++++++++++++++++++++++++ crates/leptos/src/lib.rs | 2 ++ 2 files changed, 47 insertions(+) create mode 100644 crates/leptos/src/chip.rs diff --git a/crates/leptos/src/chip.rs b/crates/leptos/src/chip.rs new file mode 100644 index 0000000..6eeaed3 --- /dev/null +++ b/crates/leptos/src/chip.rs @@ -0,0 +1,45 @@ +use components_core::{BASE_CLASS, concat}; +use leptos::prelude::*; +use leptos::{IntoView, component, view}; + +use crate::icons::{Location, StarBold}; + +#[derive(Default, Debug, PartialEq)] +pub enum Variant { + #[default] + Featured, + Numeric, + Description, + Location, + Small, +} + +impl Variant { + pub fn icon(&self) -> Option { + match self { + Variant::Featured => Some(view! { }.into_any()), + Variant::Small | Variant::Location => Some(view! { }.into_any()), + _ => None, + } + } +} + +#[component] +pub fn Chip( + #[prop(into)] label: String, + #[prop(into, optional)] class: String, + #[prop(into, optional)] variant: Variant, +) -> impl IntoView { + let class = crate::tw!( + concat!(BASE_CLASS, "-chip"), + format!("{BASE_CLASS}-chip--{variant:?}"), + class + ); + + view! { +
+ {variant.icon()} + {(variant != Variant::Numeric).then_some(format!("#{label}")).unwrap_or(label)} +
+ } +} diff --git a/crates/leptos/src/lib.rs b/crates/leptos/src/lib.rs index eea841f..909ced2 100644 --- a/crates/leptos/src/lib.rs +++ b/crates/leptos/src/lib.rs @@ -4,6 +4,7 @@ pub mod avatar; pub mod badge; pub mod button; pub mod card; +pub mod chip; pub mod flap; pub mod icons; pub mod level; @@ -20,6 +21,7 @@ pub mod prelude { pub use crate::badge::{Badge, Type as BadgeType, Variant as BadgeVariant}; pub use crate::button::{Button, Variant as ButtonVariant}; pub use crate::card::Card; + pub use crate::chip::{Chip, Variant as ChipVariant}; pub use crate::flap::Flap; pub use crate::level::{Level, Variant as LevelVariant}; pub use crate::progress_bar::ProgressBar; From 3ea9b45973f9b54c9486b09178c9564f7362b298 Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Mon, 14 Jul 2025 00:22:36 -0400 Subject: [PATCH 19/21] feat(leptos): add input component --- crates/leptos/src/input.rs | 35 +++++++++++++++++++++++++++++++++++ crates/leptos/src/lib.rs | 2 ++ 2 files changed, 37 insertions(+) create mode 100644 crates/leptos/src/input.rs diff --git a/crates/leptos/src/input.rs b/crates/leptos/src/input.rs new file mode 100644 index 0000000..b202d75 --- /dev/null +++ b/crates/leptos/src/input.rs @@ -0,0 +1,35 @@ +use components_core::{BASE_CLASS, concat}; +use leptos::prelude::*; +use leptos::{IntoView, component, view}; + +#[component] +pub fn Input( + #[prop(into)] has_error: ReadSignal, + #[prop(into)] disabled: ReadSignal, + #[prop(into, optional)] class: String, + #[prop(into, optional)] error_message: String, + #[prop(into)] icon: Option, +) -> impl IntoView { + let input_class = crate::tw!( + concat!(BASE_CLASS, "-input"), + has_error + .get() + .then_some(concat!(BASE_CLASS, "-input--error")), + class + ); + + view! { +
+
+ {icon.map(|icon| view! { {icon()} })} + +
+ {has_error.get().then_some( + view! { {error_message} } + )} +
+ } +} diff --git a/crates/leptos/src/lib.rs b/crates/leptos/src/lib.rs index 909ced2..26ddf6e 100644 --- a/crates/leptos/src/lib.rs +++ b/crates/leptos/src/lib.rs @@ -7,6 +7,7 @@ pub mod card; pub mod chip; pub mod flap; pub mod icons; +pub mod input; pub mod level; pub mod progress_bar; pub mod radio; @@ -23,6 +24,7 @@ pub mod prelude { pub use crate::card::Card; pub use crate::chip::{Chip, Variant as ChipVariant}; pub use crate::flap::Flap; + pub use crate::input::Input; pub use crate::level::{Level, Variant as LevelVariant}; pub use crate::progress_bar::ProgressBar; pub use crate::tag::Tag; From 198b437b3acc4155fc6a2c02b9469683c1bd7ce5 Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Mon, 14 Jul 2025 01:09:02 -0400 Subject: [PATCH 20/21] feat(leptos): add search input component --- crates/leptos/src/input.rs | 4 ++ crates/leptos/src/input/search.rs | 101 ++++++++++++++++++++++++++++++ crates/leptos/src/lib.rs | 2 +- 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 crates/leptos/src/input/search.rs diff --git a/crates/leptos/src/input.rs b/crates/leptos/src/input.rs index b202d75..d6138d3 100644 --- a/crates/leptos/src/input.rs +++ b/crates/leptos/src/input.rs @@ -2,6 +2,10 @@ use components_core::{BASE_CLASS, concat}; use leptos::prelude::*; use leptos::{IntoView, component, view}; +mod search; + +pub use search::{Filter, InputSearch}; + #[component] pub fn Input( #[prop(into)] has_error: ReadSignal, diff --git a/crates/leptos/src/input/search.rs b/crates/leptos/src/input/search.rs new file mode 100644 index 0000000..ebef459 --- /dev/null +++ b/crates/leptos/src/input/search.rs @@ -0,0 +1,101 @@ +use components_core::{BASE_CLASS, concat}; +use leptos::prelude::*; +use leptos::{IntoView, component, view}; + +use crate::icons::{Filter as FilterIcon, Search as SearchIcon}; +use crate::tag::Tag; + +#[derive(Clone, Debug)] +pub struct Filter { + pub label: String, + pub value: String, +} + +#[component] +pub fn InputSearch( + #[prop(into, optional)] filters: Option>, + #[prop(into, optional)] active_filters: Vec, + #[prop(into)] on_change_filter: Callback, ()>, +) -> impl IntoView { + let (filter_modal, set_filter_modal) = signal(false); + let has_filter = filters.as_ref().map_or(false, |f| !f.is_empty()); + + let handle_select_filter = { + let active_filters = active_filters.clone(); + + move |filter: Filter, is_selected: bool| { + if !is_selected { + let mut new_filters = active_filters.clone(); + new_filters.push(filter); + on_change_filter.run(new_filters); + } else { + let new_filters = active_filters + .iter() + .filter(|f| f.value != filter.value) + .cloned() + .collect(); + on_change_filter.run(new_filters); + } + } + }; + + let handle_close_on_click_input = move || { + if has_filter { + set_filter_modal.set(false); + } + }; + + view! { +
+ +
+ {has_filter.then(|| view! { + + })} +
+ {filter_modal.get().then(|| { + view! { +
    + {filters.map(|filters| filters.iter().map(|filter| { + let is_selected = active_filters.iter().any(|f| f.value == filter.value); + let filter = filter.clone(); + let handle_select_filter = handle_select_filter.clone(); + view! { +
  • + +
  • + } + }).collect::>()).unwrap_or_default()} +
+ }})} +
+
+
+ } +} diff --git a/crates/leptos/src/lib.rs b/crates/leptos/src/lib.rs index 26ddf6e..5a31048 100644 --- a/crates/leptos/src/lib.rs +++ b/crates/leptos/src/lib.rs @@ -24,7 +24,7 @@ pub mod prelude { pub use crate::card::Card; pub use crate::chip::{Chip, Variant as ChipVariant}; pub use crate::flap::Flap; - pub use crate::input::Input; + pub use crate::input::{Filter as SearchFilter, Input, InputSearch}; pub use crate::level::{Level, Variant as LevelVariant}; pub use crate::progress_bar::ProgressBar; pub use crate::tag::Tag; From 4cf9c029d3810e279d0415f13ccd78746ecd2633 Mon Sep 17 00:00:00 2001 From: Sergio Ribera <56278796+SergioRibera@users.noreply.github.com> Date: Wed, 16 Jul 2025 00:06:11 -0400 Subject: [PATCH 21/21] fix(leptos): some sugested fixes --- crates/leptos/src/avatar.rs | 8 ++++---- crates/leptos/src/flap.rs | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/leptos/src/avatar.rs b/crates/leptos/src/avatar.rs index 8be3e49..f859b6f 100644 --- a/crates/leptos/src/avatar.rs +++ b/crates/leptos/src/avatar.rs @@ -4,8 +4,8 @@ use leptos::prelude::*; #[component] pub fn Avatar( #[prop(into)] url: String, - #[prop(into, optional)] alt: Option, - #[prop(into, optional, default = Some(32))] size: Option, + #[prop(into, optional)] alt: String, + #[prop(into, optional, default = 32)] size: i32, #[prop(into, optional)] class: String, ) -> impl IntoView { let class = crate::tw!(concat!(BASE_CLASS, "-avatar"), class); @@ -13,8 +13,8 @@ pub fn Avatar( view! {
{alt}
diff --git a/crates/leptos/src/flap.rs b/crates/leptos/src/flap.rs index e4f6e72..9e21d4c 100644 --- a/crates/leptos/src/flap.rs +++ b/crates/leptos/src/flap.rs @@ -3,6 +3,8 @@ use leptos::prelude::*; use leptos::{IntoView, component, view}; use tailwind_fuse::{AsTailwindClass, TwVariant}; +use crate::icons::StarBold; + #[derive(TwVariant, PartialEq)] pub enum Variant { #[tw(default, class = "text-primary-400")] @@ -41,7 +43,7 @@ pub fn Flap( (variant == Variant::Highlight).then_some(concat!(BASE_CLASS, "-flap__view--icon")), )} > - {(variant == Variant::Highlight).then_some(view! { <> })} + {(variant == Variant::Highlight).then_some(view! { })} {label.clone()}