Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Skip non selectable items #456

Draft
wants to merge 2 commits into
base: feature/v5
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 62 additions & 14 deletions src/lib/Select.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@
filterGroupedItems,
});

$: if (filteredItems) hoverItemIndex = 0;
$: if (filteredItems) setHoverIndex(0);

beforeUpdate(async () => {
prev_value = value;
Expand Down Expand Up @@ -357,9 +357,9 @@
e.preventDefault();

if (listOpen) {
setHoverIndex(1);
changeHoverIndex(1);
} else {
hoverItemIndex = 0;
setHoverIndex(0);
listOpen = true;
activeValue = undefined;
}
Expand All @@ -369,7 +369,7 @@
e.preventDefault();

if (listOpen) {
setHoverIndex(-1);
changeHoverIndex(-1);
} else {
listOpen = true;
activeValue = undefined;
Expand Down Expand Up @@ -438,7 +438,7 @@

function handleClick() {
if (disabled) return;
hoverItemIndex = 0;
setHoverIndex(0);
listOpen = !listOpen;
if (listOpen && !focused) handleFocus();
}
Expand Down Expand Up @@ -551,7 +551,7 @@

function handleHover(i) {
if (isScrolling) return;
hoverItemIndex = i;
setHoverIndex(i);
}

function handleItemClick(args) {
Expand All @@ -565,17 +565,65 @@
}
}

/**
* Converts a desired index in a index that is in bound with `filteredItems`.
*
* desiredIndex > bigger than array size -> 0
*
* desiredIndex < 0 -> last array index
* @param {number} desiredIndex
* @returns {number} A version of the desired index that is in bound
*/
function getInBoundIndex(desiredIndex) {
if (desiredIndex > filteredItems.length) return 0;
if (desiredIndex < 0) return filteredItems.length - 1;
return desiredIndex;
}

let scrollToHoverItem = 0;
function setHoverIndex(increment) {
if (increment > 0 && hoverItemIndex === filteredItems.length - 1) {
hoverItemIndex = 0;
} else if (increment < 0 && hoverItemIndex === 0) {
hoverItemIndex = filteredItems.length - 1;
} else {
hoverItemIndex = hoverItemIndex + increment;

/**
* Increments or decrements the `hoverItemIndex` while keeping the index in bound
* and skipping indexes with non selectable items.
* @param {number} increment Positive or negative integer for amount and direction in which the index should change
* @returns {number} The first index that fulfilled the requirements and was subsequently set
*/
function changeHoverIndex(increment) {
// Get a in bound index with the applied change
let newIndex = getInBoundIndex(hoverItemIndex + increment);

// Go further in the wished direction until there is a selectable item
while (!isItemSelectable(filteredItems[newIndex])) {
if (increment < 0) newIndex--;
if (increment > 0) newIndex++;
newIndex = getInBoundIndex(newIndex);
}

scrollToHoverItem = hoverItemIndex;
// Set the new index
hoverItemIndex = newIndex;
scrollToHoverItem = newIndex;

return newIndex;
}

/**
* Set the `hoverItemIndex` while keeping the index in bound and skipping
* indexes with non selectable items.
* @param {number} newIndex The new desired index
* @returns {number} The first index that fulfilled the requirements and was subsequently set
*/
function setHoverIndex(newIndex) {
newIndex = getInBoundIndex(newIndex);

// Increment the index until the item is selectable
while (!isItemSelectable(filteredItems[newIndex])) {
newIndex++;
newIndex = getInBoundIndex(newIndex);
}

hoverItemIndex = newIndex;

return newIndex;
}

function isItemActive(item, value, itemId) {
Expand Down