diff --git a/frontend/src/components/hooks/use_random.rs b/frontend/src/components/hooks/use_random.rs index 049f410..0b9961e 100644 --- a/frontend/src/components/hooks/use_random.rs +++ b/frontend/src/components/hooks/use_random.rs @@ -1,5 +1,3 @@ -use leptos::prelude::*; - pub fn use_random_id_for(prefix: &str) -> String { format!("{}_{}", prefix, js_sys::Math::random().to_string().replace(".", "")) } diff --git a/frontend/src/components/hooks/use_theme_mode.rs b/frontend/src/components/hooks/use_theme_mode.rs index fd44f23..ce8f828 100644 --- a/frontend/src/components/hooks/use_theme_mode.rs +++ b/frontend/src/components/hooks/use_theme_mode.rs @@ -8,26 +8,15 @@ pub struct ThemeMode { const LOCALSTORAGE_KEY: &str = "darkmode"; -/// Hook to access the dark mode context -/// -/// Returns the ThemeMode instance from context for easy access pub fn use_theme_mode() -> ThemeMode { expect_context::() } -/* ========================================================== */ -/* ✨ FUNCTIONS ✨ */ -/* ========================================================== */ - impl ThemeMode { - #[must_use] - /// Initializes a new ThemeMode instance. pub fn init() -> Self { let theme_mode = Self { state: RwSignal::new(false) }; - provide_context(theme_mode); - // Use Effect to handle browser-only initialization Effect::new(move |_| { let initial = Self::get_storage_state().unwrap_or(Self::prefers_dark_mode()); theme_mode.state.set(initial); @@ -43,45 +32,14 @@ impl ThemeMode { }); } - pub fn set_dark(&self) { - self.set(true); - } - - pub fn set_light(&self) { - self.set(false); - } - - /// - `dark`: Set to `true` for dark mode, and `false` for light mode. - pub fn set(&self, dark: bool) { - self.state.set(dark); - Self::set_storage_state(dark); - } - - #[must_use] pub fn get(&self) -> bool { self.state.get() } - #[must_use] - pub fn is_dark(&self) -> bool { - self.state.get() - } - - #[must_use] - pub fn is_light(&self) -> bool { - !self.state.get() - } - - /* ========================================================== */ - /* ✨ FUNCTIONS ✨ */ - /* ========================================================== */ - - /// Retrieves the local storage object, if available. fn get_storage() -> Option { window().local_storage().ok().flatten() } - /// Retrieves the dark mode state from local storage, if available. fn get_storage_state() -> Option { Self::get_storage() .and_then(|storage| storage.get(LOCALSTORAGE_KEY).ok()) @@ -89,7 +47,6 @@ impl ThemeMode { .and_then(|entry| entry.parse::().ok()) } - /// Checks whether the user's system prefers dark mode based on media queries. fn prefers_dark_mode() -> bool { window() .match_media("(prefers-color-scheme: dark)") @@ -99,10 +56,9 @@ impl ThemeMode { .unwrap_or_default() } - /// Stores the dark mode state in local storage. fn set_storage_state(state: bool) { if let Some(storage) = Self::get_storage() { - storage.set(LOCALSTORAGE_KEY, state.to_string().as_str()).ok(); + let _ = storage.set(LOCALSTORAGE_KEY, state.to_string().as_str()); } } -} \ No newline at end of file +} diff --git a/frontend/src/components/torrent/table.rs b/frontend/src/components/torrent/table.rs index c3f0eaa..862f0bd 100644 --- a/frontend/src/components/torrent/table.rs +++ b/frontend/src/components/torrent/table.rs @@ -7,7 +7,6 @@ use crate::store::{get_action_messages, show_toast}; use crate::api; use shared::NotificationLevel; use crate::components::context_menu::TorrentContextMenu; -use crate::components::ui::card::{Card, CardHeader, CardTitle, CardContent as CardBody}; use crate::components::ui::data_table::*; use crate::components::ui::checkbox::Checkbox; use crate::components::ui::badge::{Badge, BadgeVariant}; diff --git a/frontend/src/components/ui/badge.rs b/frontend/src/components/ui/badge.rs index 329aed3..fc0ad12 100644 --- a/frontend/src/components/ui/badge.rs +++ b/frontend/src/components/ui/badge.rs @@ -6,7 +6,6 @@ pub enum BadgeVariant { #[default] Default, Secondary, - Outline, Destructive, Success, Warning, @@ -22,7 +21,6 @@ pub fn Badge( let variant_classes = match variant { BadgeVariant::Default => "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", BadgeVariant::Secondary => "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", - BadgeVariant::Outline => "text-foreground", BadgeVariant::Destructive => "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", BadgeVariant::Success => "border-transparent bg-green-500/10 text-green-600 dark:text-green-400 border-green-500/20", BadgeVariant::Warning => "border-transparent bg-yellow-500/10 text-yellow-600 dark:text-yellow-400 border-yellow-500/20", diff --git a/frontend/src/components/ui/context_menu.rs b/frontend/src/components/ui/context_menu.rs index f293047..233987c 100644 --- a/frontend/src/components/ui/context_menu.rs +++ b/frontend/src/components/ui/context_menu.rs @@ -209,7 +209,7 @@ pub fn ContextMenuTrigger( class=trigger_class data-name="ContextMenuTrigger" data-context-trigger=ctx.target_id - on:contextmenu=move |e: web_sys::MouseEvent| { + on:contextmenu=move |_e: web_sys::MouseEvent| { if let Some(cb) = on_open { cb.run(()); } diff --git a/frontend/src/components/ui/data_table.rs b/frontend/src/components/ui/data_table.rs index 25a6407..c71aede 100644 --- a/frontend/src/components/ui/data_table.rs +++ b/frontend/src/components/ui/data_table.rs @@ -1,6 +1,6 @@ // * Reuse @table.rs pub use crate::components::ui::table::{ - Table as DataTable, TableBody as DataTableBody, TableCaption as DataTableCaption, TableCell as DataTableCell, - TableFooter as DataTableFooter, TableHead as DataTableHead, TableHeader as DataTableHeader, + Table as DataTable, TableBody as DataTableBody, TableCell as DataTableCell, + TableHead as DataTableHead, TableHeader as DataTableHeader, TableRow as DataTableRow, TableWrapper as DataTableWrapper, -}; \ No newline at end of file +}; diff --git a/frontend/src/components/ui/dropdown_menu.rs b/frontend/src/components/ui/dropdown_menu.rs index 1c7f872..f8d470d 100644 --- a/frontend/src/components/ui/dropdown_menu.rs +++ b/frontend/src/components/ui/dropdown_menu.rs @@ -94,8 +94,6 @@ pub fn DropdownMenuAction( #[prop(optional, into)] class: String, #[prop(optional, into)] href: Option, ) -> impl IntoView { - let _ctx = expect_context::(); - let class = tw_merge!( "inline-flex gap-2 items-center w-full text-sm text-left transition-colors duration-200 focus:outline-none focus-visible:outline-none text-popover-foreground [&_svg:not([class*='size-'])]:size-4 hover:bg-accent hover:text-accent-foreground", class @@ -175,17 +173,15 @@ pub enum DropdownMenuAlign { #[derive(Clone)] struct DropdownMenuContext { target_id: String, - align: DropdownMenuAlign, } #[component] pub fn DropdownMenu( children: Children, - #[prop(default = DropdownMenuAlign::default())] align: DropdownMenuAlign, ) -> impl IntoView { let dropdown_target_id = use_random_id_for("dropdown"); - let ctx = DropdownMenuContext { target_id: dropdown_target_id.clone(), align }; + let ctx = DropdownMenuContext { target_id: dropdown_target_id.clone() }; view! { @@ -252,12 +248,13 @@ pub enum DropdownMenuPosition { pub fn DropdownMenuContent( children: Children, #[prop(optional, into)] class: String, + #[prop(default = DropdownMenuAlign::default())] align: DropdownMenuAlign, #[prop(default = DropdownMenuPosition::default())] position: DropdownMenuPosition, ) -> impl IntoView { let ctx = expect_context::(); let base_classes = "z-50 p-1 rounded-md border bg-card shadow-md h-fit fixed transition-all duration-200 data-[state=closed]:opacity-0 data-[state=closed]:scale-95 data-[state=open]:opacity-100 data-[state=open]:scale-100"; - let width_class = match ctx.align { + let width_class = match align { DropdownMenuAlign::Center => "min-w-full", _ => "w-[180px]", }; @@ -265,7 +262,7 @@ pub fn DropdownMenuContent( let class = tw_merge!(width_class, base_classes, class); let target_id_for_script = ctx.target_id.clone(); - let align_for_script = match ctx.align { + let align_for_script = match align { DropdownMenuAlign::Start => "start", DropdownMenuAlign::StartOuter => "start-outer", DropdownMenuAlign::End => "end", @@ -442,26 +439,6 @@ pub fn DropdownMenuContent( trigger.addEventListener('click', (e) => {{ e.stopPropagation(); - // Check if any other dropdown is open - const allDropdowns = document.querySelectorAll('[data-target=\"target__dropdown\"]'); - let otherDropdownOpen = false; - allDropdowns.forEach(dd => {{ - if (dd !== dropdown && dd.getAttribute('data-state') === 'open') {{ - otherDropdownOpen = true; - dd.setAttribute('data-state', 'closed'); - dd.style.pointerEvents = 'none'; - // Unlock scroll - if (window.ScrollLock) {{ - window.ScrollLock.unlock(200); - }} - }} - }}); - - // If another dropdown was open, just close it and don't open this one - if (otherDropdownOpen) {{ - return; - }} - // Normal toggle behavior if (isOpen) {{ closeDropdown(); @@ -533,4 +510,4 @@ pub fn DropdownMenuSubItem(children: Children, #[prop(optional, into)] class: St {children()} } -} \ No newline at end of file +} diff --git a/frontend/src/components/ui/multi_select.rs b/frontend/src/components/ui/multi_select.rs index 182e8bb..d5ddc0d 100644 --- a/frontend/src/components/ui/multi_select.rs +++ b/frontend/src/components/ui/multi_select.rs @@ -9,7 +9,7 @@ use crate::components::hooks::use_can_scroll_vertical::use_can_scroll_vertical; use crate::components::hooks::use_random::use_random_id_for; // * Reuse @select.rs pub use crate::components::ui::select::{ - SelectGroup as MultiSelectGroup, SelectItem as MultiSelectItem, SelectLabel as MultiSelectLabel, + SelectGroup as MultiSelectGroup, SelectItem as MultiSelectItem, }; #[derive(Clone, Copy, PartialEq, Eq, Default)] diff --git a/frontend/src/components/ui/sheet.rs b/frontend/src/components/ui/sheet.rs index 06602bc..c66630c 100644 --- a/frontend/src/components/ui/sheet.rs +++ b/frontend/src/components/ui/sheet.rs @@ -31,9 +31,6 @@ pub struct SheetContext { /* ✨ FUNCTIONS ✨ */ /* ========================================================== */ -pub type SheetVariant = ButtonVariant; -pub type SheetSize = ButtonSize; - #[component] pub fn Sheet(children: Children, #[prop(optional, into)] class: String) -> impl IntoView { let sheet_target_id = use_random_id_for("sheet"); @@ -203,7 +200,7 @@ pub fn SheetContent( target_id_for_script, )} - }.into_any() + } } /* ========================================================== */