feat: integrate shadcn/ui, add Button component, and refactor App UI
This commit is contained in:
62
frontend/src/components/ui/button.rs
Normal file
62
frontend/src/components/ui/button.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
use leptos::*;
|
||||
use crate::utils::cn;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
||||
pub enum ButtonVariant {
|
||||
#[default]
|
||||
Default,
|
||||
Destructive,
|
||||
Outline,
|
||||
Secondary,
|
||||
Ghost,
|
||||
Link,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
||||
pub enum ButtonSize {
|
||||
#[default]
|
||||
Default,
|
||||
Sm,
|
||||
Lg,
|
||||
Icon,
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn Button(
|
||||
#[prop(into, optional)] variant: ButtonVariant,
|
||||
#[prop(into, optional)] size: ButtonSize,
|
||||
#[prop(into, optional)] class: String,
|
||||
#[prop(into, optional)] on_click: Option<Callback<web_sys::MouseEvent>>,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
let variant_classes = match variant {
|
||||
ButtonVariant::Default => "bg-primary text-primary-foreground hover:bg-primary/90",
|
||||
ButtonVariant::Destructive => "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
||||
ButtonVariant::Outline => "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
||||
ButtonVariant::Secondary => "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
ButtonVariant::Ghost => "hover:bg-accent hover:text-accent-foreground",
|
||||
ButtonVariant::Link => "text-primary underline-offset-4 hover:underline",
|
||||
};
|
||||
|
||||
let size_classes = match size {
|
||||
ButtonSize::Default => "h-10 px-4 py-2",
|
||||
ButtonSize::Sm => "h-9 rounded-md px-3",
|
||||
ButtonSize::Lg => "h-11 rounded-md px-8",
|
||||
ButtonSize::Icon => "h-10 w-10",
|
||||
};
|
||||
|
||||
let base_classes = "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50";
|
||||
|
||||
view! {
|
||||
<button
|
||||
class=cn(format!("{} {} {} {}", base_classes, variant_classes, size_classes, class))
|
||||
on:click=move |e| {
|
||||
if let Some(cb) = on_click {
|
||||
cb.call(e);
|
||||
}
|
||||
}
|
||||
>
|
||||
{children()}
|
||||
</button>
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user