feat: scroll selected option into view for dropdown, highlight selected on regular dropdowns

This commit is contained in:
Maya 2026-03-22 23:15:19 +03:00
parent 34a1a5df64
commit eb301387ec
2 changed files with 24 additions and 10 deletions

View File

@ -22,8 +22,6 @@
}: Props = $props();
let open = $state(false);
let hover = $state(false);
let isUp = $state(false);
let dropdown = $state<HTMLDivElement>();
let menuElement = $state<HTMLDivElement>();
let button = $state<HTMLButtonElement>();
@ -38,11 +36,6 @@
const select = (option: string | { value: string; label: string }) => {
const selectedValue = getValue(option);
const oldIndex = options.findIndex((opt) => getValue(opt) === selected);
const newIndex = options.findIndex(
(opt) => getValue(opt) === selectedValue,
);
isUp = oldIndex > newIndex;
selected = selectedValue;
onselect?.(selectedValue);
toggle();
@ -61,6 +54,15 @@
}
};
const scrollView = () => {
if (!menuElement) return;
const selectedButton = menuElement.querySelector(
"[data-selected='true']",
) as HTMLButtonElement | null;
if (!selectedButton) return;
selectedButton.scrollIntoView({ block: "start" });
};
// outside clicks
$effect(() => {
clickHandler = (e: MouseEvent) => {
@ -82,6 +84,7 @@
document.body.appendChild(menuElement);
menuElement.style.position = "fixed";
updateMenuPosition();
requestAnimationFrame(scrollView);
return () => {
if (resizeHandler)
@ -111,8 +114,6 @@
? 'rounded-xl'
: 'rounded-full'} focus:!outline-none"
onclick={toggle}
onmouseenter={() => (hover = true)}
onmouseleave={() => (hover = false)}
{disabled}
>
<div class="grid grid-cols-1 grid-rows-1 w-fit flex-grow-0">
@ -166,7 +167,9 @@
>
{#each options as option}
<button
class="w-full p-2 px-4 text-left hover:bg-panel font-normal text-sm text-muted"
data-selected={getValue(option) === selected}
class={`w-full p-2 px-4 text-left hover:bg-panel font-normal text-sm text-muted
${getValue(option) === selected ? "bg-separator" : ""}`}
onclick={() => select(option)}
>
{getLabel(option)}

View File

@ -226,6 +226,15 @@
selectOption(filteredData.formats[0]);
};
const scrollView = () => {
if (!dropdownMenu) return;
const selectedOption = dropdownMenu.querySelector(
"[data-selected='true']",
) as HTMLButtonElement | null;
if (!selectedOption) return;
selectedOption.scrollIntoView({ block: "start" });
};
const clickDropdown = () => {
open = !open;
if (!open) return;
@ -259,6 +268,7 @@
searchInput.focus();
searchInput.select();
}
scrollView();
}, 0); // let dropdown open first
};
@ -455,6 +465,7 @@
{#if filteredData.formats.length > 0}
{#each filteredData.formats as format}
<button
data-selected={format === selected}
class="w-full p-2 text-center rounded-xl
{format === selected
? 'bg-accent text-black'