From 2c91f463758c8452561fbcc5dad8412edba8915d Mon Sep 17 00:00:00 2001 From: Philipp Dormann Date: Tue, 20 May 2025 00:47:04 +0200 Subject: [PATCH] wip --- src/components/tools/DonationCreate.svelte | 250 ++++++++++++++++++++- src/components/tools/VirtualSelect.svelte | 25 ++- 2 files changed, 262 insertions(+), 13 deletions(-) diff --git a/src/components/tools/DonationCreate.svelte b/src/components/tools/DonationCreate.svelte index db6fa32f..c681a0bc 100644 --- a/src/components/tools/DonationCreate.svelte +++ b/src/components/tools/DonationCreate.svelte @@ -10,15 +10,245 @@ import { onMount } from "svelte"; import VirtualSelect from "./VirtualSelect.svelte"; - // - let options = ["Bulbasaur","Ivysaur","Venusaur","Charmander","Charmeleon","Charizard","Squirtle","Wartortle","Blastoise","Caterpie","Metapod","Butterfree","Weedle","Kakuna","Beedrill","Pidgey","Pidgeotto","Pidgeot","Rattata","Raticate","Spearow","Fearow","Ekans","Arbok","Pikachu","Raichu","Sandshrew","Sandslash","Nidoran♀","Nidorina","Nidoqueen","Nidoran♂","Nidorino","Nidoking","Clefairy","Clefable","Vulpix","Ninetales","Jigglypuff","Wigglytuff","Zubat","Golbat","Oddish","Gloom","Vileplume","Paras","Parasect","Venonat","Venomoth","Diglett","Dugtrio","Meowth","Persian","Psyduck","Golduck","Mankey","Primeape","Growlithe","Arcanine","Poliwag","Poliwhirl","Poliwrath","Abra","Kadabra","Alakazam","Machop","Machoke","Machamp","Bellsprout","Weepinbell","Victreebel","Tentacool","Tentacruel","Geodude","Graveler","Golem","Ponyta","Rapidash","Slowpoke","Slowbro","Magnemite","Magneton","Farfetch'd","Doduo","Dodrio","Seel","Dewgong","Grimer","Muk","Shellder","Cloyster","Gastly","Haunter","Gengar","Onix","Drowzee","Hypno","Krabby","Kingler","Voltorb","Electrode","Exeggcute","Exeggutor","Cubone","Marowak","Hitmonlee","Hitmonchan","Lickitung","Koffing","Weezing","Rhyhorn","Rhydon","Chansey","Tangela","Kangaskhan","Horsea","Seadra","Goldeen","Seaking","Staryu","Starmie","Mr. Mime","Scyther","Jynx","Electabuzz","Magmar","Pinsir","Tauros","Magikarp","Gyarados","Lapras","Ditto","Eevee","Vaporeon","Jolteon","Flareon","Porygon","Omanyte","Omastar","Kabuto","Kabutops","Aerodactyl","Snorlax","Articuno","Zapdos","Moltres","Dratini","Dragonair","Dragonite","Mewtwo","Mew","Chikorita","Bayleef","Meganium","Cyndaquil","Quilava","Typhlosion","Totodile","Croconaw","Feraligatr","Sentret","Furret","Hoothoot","Noctowl","Ledyba","Ledian","Spinarak","Ariados","Crobat","Chinchou","Lanturn","Pichu","Cleffa","Igglybuff","Togepi","Togetic","Natu","Xatu","Mareep","Flaaffy","Ampharos","Bellossom","Marill","Azumarill","Sudowoodo","Politoed","Hoppip","Skiploom","Jumpluff","Aipom","Sunkern","Sunflora","Yanma","Wooper","Quagsire","Espeon","Umbreon","Murkrow","Slowking","Misdreavus","Unown","Wobbuffet","Girafarig","Pineco","Forretress","Dunsparce","Gligar","Steelix","Snubbull","Granbull","Qwilfish","Scizor","Shuckle","Heracross","Sneasel","Teddiursa","Ursaring","Slugma","Magcargo","Swinub","Piloswine","Corsola","Remoraid","Octillery","Delibird","Mantine","Skarmory","Houndour","Houndoom"]; - let selectedOption; + // + let options = [ + "Bulbasaur", + "Ivysaur", + "Venusaur", + "Charmander", + "Charmeleon", + "Charizard", + "Squirtle", + "Wartortle", + "Blastoise", + "Caterpie", + "Metapod", + "Butterfree", + "Weedle", + "Kakuna", + "Beedrill", + "Pidgey", + "Pidgeotto", + "Pidgeot", + "Rattata", + "Raticate", + "Spearow", + "Fearow", + "Ekans", + "Arbok", + "Pikachu", + "Raichu", + "Sandshrew", + "Sandslash", + "Nidoran♀", + "Nidorina", + "Nidoqueen", + "Nidoran♂", + "Nidorino", + "Nidoking", + "Clefairy", + "Clefable", + "Vulpix", + "Ninetales", + "Jigglypuff", + "Wigglytuff", + "Zubat", + "Golbat", + "Oddish", + "Gloom", + "Vileplume", + "Paras", + "Parasect", + "Venonat", + "Venomoth", + "Diglett", + "Dugtrio", + "Meowth", + "Persian", + "Psyduck", + "Golduck", + "Mankey", + "Primeape", + "Growlithe", + "Arcanine", + "Poliwag", + "Poliwhirl", + "Poliwrath", + "Abra", + "Kadabra", + "Alakazam", + "Machop", + "Machoke", + "Machamp", + "Bellsprout", + "Weepinbell", + "Victreebel", + "Tentacool", + "Tentacruel", + "Geodude", + "Graveler", + "Golem", + "Ponyta", + "Rapidash", + "Slowpoke", + "Slowbro", + "Magnemite", + "Magneton", + "Farfetch'd", + "Doduo", + "Dodrio", + "Seel", + "Dewgong", + "Grimer", + "Muk", + "Shellder", + "Cloyster", + "Gastly", + "Haunter", + "Gengar", + "Onix", + "Drowzee", + "Hypno", + "Krabby", + "Kingler", + "Voltorb", + "Electrode", + "Exeggcute", + "Exeggutor", + "Cubone", + "Marowak", + "Hitmonlee", + "Hitmonchan", + "Lickitung", + "Koffing", + "Weezing", + "Rhyhorn", + "Rhydon", + "Chansey", + "Tangela", + "Kangaskhan", + "Horsea", + "Seadra", + "Goldeen", + "Seaking", + "Staryu", + "Starmie", + "Mr. Mime", + "Scyther", + "Jynx", + "Electabuzz", + "Magmar", + "Pinsir", + "Tauros", + "Magikarp", + "Gyarados", + "Lapras", + "Ditto", + "Eevee", + "Vaporeon", + "Jolteon", + "Flareon", + "Porygon", + "Omanyte", + "Omastar", + "Kabuto", + "Kabutops", + "Aerodactyl", + "Snorlax", + "Articuno", + "Zapdos", + "Moltres", + "Dratini", + "Dragonair", + "Dragonite", + "Mewtwo", + "Mew", + "Chikorita", + "Bayleef", + "Meganium", + "Cyndaquil", + "Quilava", + "Typhlosion", + "Totodile", + "Croconaw", + "Feraligatr", + "Sentret", + "Furret", + "Hoothoot", + "Noctowl", + "Ledyba", + "Ledian", + "Spinarak", + "Ariados", + "Crobat", + "Chinchou", + "Lanturn", + "Pichu", + "Cleffa", + "Igglybuff", + "Togepi", + "Togetic", + "Natu", + "Xatu", + "Mareep", + "Flaaffy", + "Ampharos", + "Bellossom", + "Marill", + "Azumarill", + "Sudowoodo", + "Politoed", + "Hoppip", + "Skiploom", + "Jumpluff", + "Aipom", + "Sunkern", + "Sunflora", + "Yanma", + "Wooper", + "Quagsire", + "Espeon", + "Umbreon", + "Murkrow", + "Slowking", + "Misdreavus", + "Unown", + "Wobbuffet", + "Girafarig", + "Pineco", + "Forretress", + "Dunsparce", + "Gligar", + "Steelix", + "Snubbull", + "Granbull", + "Qwilfish", + "Scizor", + "Shuckle", + "Heracross", + "Sneasel", + "Teddiursa", + "Ursaring", + "Slugma", + "Magcargo", + "Swinub", + "Piloswine", + "Corsola", + "Remoraid", + "Octillery", + "Delibird", + "Mantine", + "Skarmory", + "Houndour", + "Houndoom", + ]; + let selectedOption; - function handleSelect(event) { - selectedOption = event.detail; - console.log('Selected:', selectedOption); - } - // + function handleSelect(event) { + selectedOption = event.detail; + console.log("Selected:", selectedOption); + } + // let runners = []; let donors = []; @@ -119,6 +349,10 @@ { + // Example: Match if option starts with search term (case-insensitive) + return option.toLowerCase().startsWith(searchTerm.toLowerCase()); + }} bind:selected={selectedOption} placeholder="Search fruits..." on:select={handleSelect} diff --git a/src/components/tools/VirtualSelect.svelte b/src/components/tools/VirtualSelect.svelte index ebd1e0ad..9e7f2de7 100644 --- a/src/components/tools/VirtualSelect.svelte +++ b/src/components/tools/VirtualSelect.svelte @@ -5,6 +5,7 @@ export let options = []; export let selected = null; export let placeholder = "Search options..."; + export let filterFn = null; // Custom filter function // Internal state let searchTerm = ""; @@ -22,9 +23,11 @@ // Filter options based on search term $: { filteredOptions = searchTerm - ? options.filter((option) => - option.toLowerCase().includes(searchTerm.toLowerCase()) - ) + ? filterFn + ? options.filter((option) => filterFn(option, searchTerm)) + : options.filter((option) => + option.toLowerCase().includes(searchTerm.toLowerCase()) + ) : options; // Reset scroll and focus when filtered options change startIndex = 0; @@ -112,6 +115,10 @@ } else if (event.key === "Enter" && index >= 0) { event.preventDefault(); selectOption(filteredOptions[index]); + } else if (event.key === "Escape") { + event.preventDefault(); + isOpen = false; + focusedIndex = -1; } } @@ -155,7 +162,9 @@ type="text" bind:value={searchTerm} placeholder={selected || placeholder} - class="w-full bg-transparent focus:outline-none text-gray-700" + class="w-full bg-transparent focus:outline-none {selected + ? 'text-black' + : 'text-gray-700'}" on:focus={handleInputFocus} on:keydown={(e) => { if (e.key === "Enter" && !isOpen) { @@ -174,7 +183,13 @@ on:click={toggleDropdown} role="button" tabindex="0" - on:keydown={(e) => e.key === "Enter" && toggleDropdown()} + on:keydown={(e) => { + if (e.key === "Enter") toggleDropdown(); + else if (e.key === "Escape") { + isOpen = false; + focusedIndex = -1; + } + }} aria-label="Toggle dropdown" >