From 31077dbd39a25eecd24a1dca0f8c9d1879265277 Mon Sep 17 00:00:00 2001 From: HsiangNianian Date: Thu, 15 Jan 2026 17:36:36 +0800 Subject: feat: Implement custom dropdown components for version selection in BottomBar and ModLoaderSelector, enhancing user interaction and UI consistency --- ui/src/components/ModLoaderSelector.svelte | 150 ++++++++++++++++++++++++----- 1 file changed, 126 insertions(+), 24 deletions(-) (limited to 'ui/src/components/ModLoaderSelector.svelte') diff --git a/ui/src/components/ModLoaderSelector.svelte b/ui/src/components/ModLoaderSelector.svelte index d0c1b59..cb949c5 100644 --- a/ui/src/components/ModLoaderSelector.svelte +++ b/ui/src/components/ModLoaderSelector.svelte @@ -6,7 +6,7 @@ ForgeVersion, ModLoaderType, } from "../types"; - import { Loader2, Download, AlertCircle, Check } from 'lucide-svelte'; + import { Loader2, Download, AlertCircle, Check, ChevronDown } from 'lucide-svelte'; interface Props { selectedGameVersion: string; @@ -23,10 +23,15 @@ // Fabric state let fabricLoaders = $state([]); let selectedFabricLoader = $state(""); + let isFabricDropdownOpen = $state(false); // Forge state let forgeVersions = $state([]); let selectedForgeVersion = $state(""); + let isForgeDropdownOpen = $state(false); + + let fabricDropdownRef = $state(null); + let forgeDropdownRef = $state(null); // Load mod loader versions when game version changes $effect(() => { @@ -111,6 +116,44 @@ loadModLoaderVersions(); } } + + function handleFabricClickOutside(e: MouseEvent) { + if (fabricDropdownRef && !fabricDropdownRef.contains(e.target as Node)) { + isFabricDropdownOpen = false; + } + } + + function handleForgeClickOutside(e: MouseEvent) { + if (forgeDropdownRef && !forgeDropdownRef.contains(e.target as Node)) { + isForgeDropdownOpen = false; + } + } + + $effect(() => { + if (isFabricDropdownOpen) { + document.addEventListener('click', handleFabricClickOutside); + return () => document.removeEventListener('click', handleFabricClickOutside); + } + }); + + $effect(() => { + if (isForgeDropdownOpen) { + document.addEventListener('click', handleForgeClickOutside); + return () => document.removeEventListener('click', handleForgeClickOutside); + } + }); + + let selectedFabricLabel = $derived( + fabricLoaders.find(l => l.version === selectedFabricLoader) + ? `${selectedFabricLoader}${fabricLoaders.find(l => l.version === selectedFabricLoader)?.stable ? ' (stable)' : ''}` + : selectedFabricLoader || 'Select version' + ); + + let selectedForgeLabel = $derived( + forgeVersions.find(v => v.version === selectedForgeVersion) + ? `${selectedForgeVersion}${forgeVersions.find(v => v.version === selectedForgeVersion)?.recommended ? ' (Recommended)' : ''}` + : selectedForgeVersion || 'Select version' + );
@@ -163,18 +206,48 @@ -
- + {selectedFabricLabel} + + + + {#if isFabricDropdownOpen} +
+ {#each fabricLoaders as loader} + + {/each} +
+ {/if}
@@ -199,19 +272,48 @@ -
- + {selectedForgeLabel} + + + + {#if isForgeDropdownOpen} +
+ {#each forgeVersions as version} + + {/each} +
+ {/if}
-- cgit v1.2.3-70-g09d2