From 2b514142e6c226bb40dd2ad904b9be93135b1378 Mon Sep 17 00:00:00 2001 From: asepharyana Date: Fri, 3 Jul 2026 17:41:07 +0700 Subject: [PATCH] =?UTF-8?q?feat(leptos):=20UI=20primitives=20=E2=80=94=20B?= =?UTF-8?q?utton,=20Badge,=20Card?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/frontend-leptos/frontend/src/lib.rs | 1 + .../frontend-leptos/frontend/src/ui/badge.rs | 42 ++++++++++++ .../frontend-leptos/frontend/src/ui/button.rs | 67 +++++++++++++++++++ .../frontend-leptos/frontend/src/ui/card.rs | 46 +++++++++++++ .../frontend-leptos/frontend/src/ui/mod.rs | 4 ++ 5 files changed, 160 insertions(+) create mode 100644 services/frontend-leptos/frontend/src/ui/badge.rs create mode 100644 services/frontend-leptos/frontend/src/ui/button.rs create mode 100644 services/frontend-leptos/frontend/src/ui/card.rs create mode 100644 services/frontend-leptos/frontend/src/ui/mod.rs diff --git a/services/frontend-leptos/frontend/src/lib.rs b/services/frontend-leptos/frontend/src/lib.rs index 7314da4..096f807 100644 --- a/services/frontend-leptos/frontend/src/lib.rs +++ b/services/frontend-leptos/frontend/src/lib.rs @@ -1,4 +1,5 @@ pub mod app; +pub mod ui; use wasm_bindgen::prelude::*; diff --git a/services/frontend-leptos/frontend/src/ui/badge.rs b/services/frontend-leptos/frontend/src/ui/badge.rs new file mode 100644 index 0000000..ed54523 --- /dev/null +++ b/services/frontend-leptos/frontend/src/ui/badge.rs @@ -0,0 +1,42 @@ +use leptos::prelude::*; + +#[derive(Clone)] +pub enum BadgeVariant { + Default, + Primary, + Success, + Warning, + Destructive, + Outline, + Info, +} + +impl Default for BadgeVariant { + fn default() -> Self { + Self::Default + } +} + +#[component] +pub fn Badge( + #[prop(optional)] variant: BadgeVariant, + children: Children, +) -> impl IntoView { + let variant_class = match variant { + BadgeVariant::Default => "", + BadgeVariant::Primary => "badge-primary", + BadgeVariant::Success => "badge-success", + BadgeVariant::Warning => "badge-warning", + BadgeVariant::Destructive => "badge-destructive", + BadgeVariant::Outline => "badge-outline", + BadgeVariant::Info => "badge-info", + }; + + let combined = format!("badge {}", variant_class); + + view! { + + {children()} + + } +} diff --git a/services/frontend-leptos/frontend/src/ui/button.rs b/services/frontend-leptos/frontend/src/ui/button.rs new file mode 100644 index 0000000..4063181 --- /dev/null +++ b/services/frontend-leptos/frontend/src/ui/button.rs @@ -0,0 +1,67 @@ +use leptos::prelude::*; + +#[derive(Clone, Default)] +pub enum ButtonVariant { + #[default] + Primary, + Secondary, + Tertiary, + Destructive, + Outline, + Ghost, + Link, +} + +#[derive(Clone)] +pub enum ButtonSize { + Default, + Sm, + Lg, + Icon, + IconSm, +} + +impl Default for ButtonSize { + fn default() -> Self { + Self::Default + } +} + +#[component] +pub fn Button( + #[prop(optional)] variant: ButtonVariant, + #[prop(optional)] size: ButtonSize, + #[prop(optional)] disabled: bool, + #[prop(optional)] class: &'static str, + #[prop(optional)] on_click: Option>, + children: Children, +) -> impl IntoView { + let variant_class = match variant { + ButtonVariant::Primary => "btn-primary", + ButtonVariant::Secondary => "btn-secondary", + ButtonVariant::Tertiary => "btn-tertiary", + ButtonVariant::Destructive => "btn-destructive", + ButtonVariant::Outline => "btn-outline", + ButtonVariant::Ghost => "btn-ghost", + ButtonVariant::Link => "btn-link", + }; + let size_class = match size { + ButtonSize::Default => "", + ButtonSize::Sm => "btn-sm", + ButtonSize::Lg => "btn-lg", + ButtonSize::Icon => "btn-icon", + ButtonSize::IconSm => "btn-icon-sm", + }; + + let combined = format!("btn {} {} {}", variant_class, size_class, class); + + view! { + + } +} diff --git a/services/frontend-leptos/frontend/src/ui/card.rs b/services/frontend-leptos/frontend/src/ui/card.rs new file mode 100644 index 0000000..e0341e0 --- /dev/null +++ b/services/frontend-leptos/frontend/src/ui/card.rs @@ -0,0 +1,46 @@ +use leptos::prelude::*; + +#[component] +pub fn Card( + #[prop(optional)] elevated: bool, + #[prop(optional)] bordered: bool, + #[prop(optional)] class: &'static str, + children: Children, +) -> impl IntoView { + let combined = format!("card {}", class); + + view! { +
+ {children()} +
+ } +} + +#[component] +pub fn CardHeader(children: Children) -> impl IntoView { + view! {
{children()}
} +} + +#[component] +pub fn CardTitle(children: Children) -> impl IntoView { + view! {

{children()}

} +} + +#[component] +pub fn CardDescription(children: Children) -> impl IntoView { + view! {

{children()}

} +} + +#[component] +pub fn CardContent(children: Children) -> impl IntoView { + view! {
{children()}
} +} + +#[component] +pub fn CardFooter(children: Children) -> impl IntoView { + view! { } +} diff --git a/services/frontend-leptos/frontend/src/ui/mod.rs b/services/frontend-leptos/frontend/src/ui/mod.rs new file mode 100644 index 0000000..cf0c674 --- /dev/null +++ b/services/frontend-leptos/frontend/src/ui/mod.rs @@ -0,0 +1,4 @@ +// services/frontend-leptos/frontend/src/ui/mod.rs +pub mod badge; +pub mod button; +pub mod card;