feat: modernize all buttons using the official rust-ui Button component
Some checks failed
Build MIPS Binary / build (push) Has been cancelled

This commit is contained in:
spinline
2026-02-12 00:23:12 +03:00
parent bbb8e8dc98
commit fa07fd88dc
5 changed files with 55 additions and 34 deletions

View File

@@ -3,6 +3,8 @@ use leptos::task::spawn_local;
use crate::components::ui::card::{Card, CardHeader, CardContent};
use crate::components::ui::input::{Input, InputType};
use crate::components::ui::button::Button;
#[component]
pub fn Login() -> impl IntoView {
let username = RwSignal::new(String::new());
@@ -74,15 +76,16 @@ pub fn Login() -> impl IntoView {
</Show>
<div class="pt-2">
<button
class="inline-flex items-center justify-center w-full h-9 px-4 py-2 rounded-md text-sm font-medium bg-primary text-primary-foreground shadow-xs hover:bg-primary/90 transition-all disabled:pointer-events-none disabled:opacity-50"
disabled=move || loading.0.get()
<Button
class="w-full"
attr:r#type="submit"
attr:disabled=move || loading.0.get()
>
<Show when=move || loading.0.get() fallback=|| "Giriş Yap">
<Show when=move || loading.0.get() fallback=|| view! { "Giriş Yap" }.into_any()>
<span class="animate-spin mr-2 h-4 w-4 border-2 border-current border-t-transparent rounded-full"></span>
"Giriş Yapılıyor..."
</Show>
</button>
</Button>
</div>
</form>
</CardContent>

View File

@@ -3,6 +3,8 @@ use leptos::task::spawn_local;
use crate::components::ui::card::{Card, CardHeader, CardContent};
use crate::components::ui::input::{Input, InputType};
use crate::components::ui::button::Button;
#[component]
pub fn Setup() -> impl IntoView {
let username = RwSignal::new(String::new());
@@ -98,15 +100,16 @@ pub fn Setup() -> impl IntoView {
</Show>
<div class="pt-2">
<button
class="inline-flex items-center justify-center w-full h-9 px-4 py-2 rounded-md text-sm font-medium bg-primary text-primary-foreground shadow-xs hover:bg-primary/90 transition-all disabled:pointer-events-none disabled:opacity-50"
disabled=move || loading.0.get()
<Button
class="w-full"
attr:r#type="submit"
attr:disabled=move || loading.0.get()
>
<Show when=move || loading.0.get() fallback=|| "Kurulumu Tamamla">
<Show when=move || loading.0.get() fallback=|| view! { "Kurulumu Tamamla" }.into_any()>
<span class="animate-spin mr-2 h-4 w-4 border-2 border-current border-t-transparent rounded-full"></span>
"Kuruluyor..."
</Show>
</button>
</Button>
</div>
</form>
</CardContent>

View File

@@ -1,5 +1,6 @@
use leptos::prelude::*;
use leptos::task::spawn_local;
use crate::components::ui::button::{Button, ButtonVariant, ButtonSize};
#[component]
pub fn Sidebar() -> impl IntoView {
@@ -137,8 +138,11 @@ pub fn Sidebar() -> impl IntoView {
<crate::components::ui::theme_toggle::ThemeToggle />
</div>
// Logout button
<button
class="inline-flex items-center justify-center size-8 rounded-md hover:bg-accent text-destructive transition-colors"
<Button
variant=ButtonVariant::Ghost
size=ButtonSize::Icon
class="text-destructive hover:bg-destructive/10"
attr:disabled=move || false
on:click=move |_| {
spawn_local(async move {
if shared::server_fns::auth::logout().await.is_ok() {
@@ -151,7 +155,7 @@ pub fn Sidebar() -> impl IntoView {
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15M12 9l-3 3m0 0l3 3m-3-3h12.75" />
</svg>
</button>
</Button>
</div>
</div>
</div>
@@ -166,13 +170,12 @@ fn SidebarButton(
#[prop(into)] label: &'static str,
count: Signal<usize>,
) -> impl IntoView {
let variant = move || if active.get() { ButtonVariant::Secondary } else { ButtonVariant::Ghost };
view! {
<button
class=move || if active.get() {
"inline-flex items-center justify-start gap-2 w-full h-8 rounded-md px-3 text-sm font-medium bg-secondary text-secondary-foreground transition-colors"
} else {
"inline-flex items-center justify-start gap-2 w-full h-8 rounded-md px-3 text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-colors"
}
<Button
variant=Signal::derive(variant)
class="justify-start gap-2 w-full h-8 px-3"
on:click=on_click
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
@@ -180,6 +183,6 @@ fn SidebarButton(
</svg>
{label}
<span class="ml-auto text-xs font-mono opacity-70">{count}</span>
</button>
</Button>
}
}

View File

@@ -4,6 +4,8 @@ use crate::components::ui::input::{Input, InputType};
use crate::store::TorrentStore;
use crate::api;
use crate::components::ui::button::{Button, ButtonVariant};
#[component]
pub fn AddTorrentDialog(
on_close: Callback<()>,
@@ -80,17 +82,16 @@ pub fn AddTorrentDialog(
})}
<div class="flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2">
<button
type="button"
class="inline-flex items-center justify-center h-9 px-4 py-2 rounded-md text-sm font-medium hover:bg-accent hover:text-accent-foreground transition-colors"
<Button
variant=ButtonVariant::Ghost
attr:r#type="button"
on:click=move |_| on_close.run(())
>
"Cancel"
</button>
<button
type="submit"
class="inline-flex items-center justify-center h-9 px-4 py-2 rounded-md text-sm font-medium bg-primary text-primary-foreground shadow-xs hover:bg-primary/90 transition-all disabled:pointer-events-none disabled:opacity-50"
disabled=move || is_loading.0.get()
</Button>
<Button
attr:r#type="submit"
attr:disabled=move || is_loading.0.get()
>
{move || if is_loading.0.get() {
leptos::either::Either::Left(view! {
@@ -100,13 +101,14 @@ pub fn AddTorrentDialog(
} else {
leptos::either::Either::Right(view! { "Add" })
}}
</button>
</Button>
</div>
</form>
// Close button (X)
<button
class="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none"
<Button
variant=ButtonVariant::Ghost
class="absolute right-2 top-2 size-8 p-0 opacity-70 hover:opacity-100"
on:click=move |_| on_close.run(())
>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4">
@@ -114,7 +116,7 @@ pub fn AddTorrentDialog(
<path d="m6 6 12 12"></path>
</svg>
<span class="sr-only">"Close"</span>
</button>
</Button>
</div>
}
}

View File

@@ -1,9 +1,11 @@
use leptos::prelude::*;
use leptos_ui::variants;
// TODO 💪 Loading state (demo_use_timeout_fn.rs and demo_button.rs)
variants! {
Button {
base: "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive w-fit hover:cursor-pointer active:scale-[0.98] active:opacity-100 touch-manipulation [-webkit-tap-highlight-color:transparent] select-none [-webkit-touch-callout:none]",
base: "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive w-fit hover:cursor-pointer active:scale-[0.98] active:opacity-100 touch-manipulation [-webkit-tap-highlight-color:transparent] select-none [-webkit-touch-callout:none]", // Using hover:cursor-pointer as workaround for href_support.
variants: {
variant: {
Default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
@@ -11,13 +13,21 @@ variants! {
Outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/5",
Secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
Ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
Accent: "bg-accent text-accent-foreground hover:bg-accent/80",
Link: "text-primary underline-offset-4 hover:underline",
//
Warning: "bg-warning text-warning-foreground hover:bg-warning/90",
Success: "bg-success text-success-foreground hover:bg-success/90",
Bordered: "bg-transparent border border-zinc-200 text-muted-foreground",
},
size: {
Default: "h-9 px-4 py-2 has-[>svg]:px-3",
Sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
Lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
Icon: "size-9",
//
Mobile: "px-6 py-3 rounded-[24px]",
Badge: "px-2.5 py-0.5 text-xs"
}
},
component: {
@@ -26,4 +36,4 @@ variants! {
support_aria_current: true
}
}
}
}