Skip to content

Instantly share code, notes, and snippets.

@johnloy
Created September 23, 2026 16:03
Show Gist options
  • Select an option

  • Save johnloy/29f2970b618b7cce4e73768de98087f4 to your computer and use it in GitHub Desktop.

Select an option

Save johnloy/29f2970b618b7cce4e73768de98087f4 to your computer and use it in GitHub Desktop.
Ensure at least one option in a multi-select set stays selected
/**
* Toggles an option in a multi-select list while guaranteeing at least one
* option stays selected.
*
* Checking adds the option. Unchecking removes it unless it is the last
* remaining selection; in that case the next option in `options` is selected
* instead (wrapping to the start). With two options, unchecking A selects B.
* With one option the same item stays on.
*/
export const toggleSelectionKeepOne = <T>(
selected: readonly T[],
toggled: T,
options: readonly T[],
nextChecked: boolean
): T[] => {
const selectedSet = new Set(selected);
if (nextChecked) {
return options.filter(
option => option === toggled || selectedSet.has(option)
);
}
const remaining = selected.filter(option => option !== toggled);
if (remaining.length > 0) {
return remaining;
}
if (options.length === 0) {
return [];
}
const currentIndex = options.indexOf(toggled);
const fallbackIndex =
currentIndex === -1 ? 0 : (currentIndex + 1) % options.length;
return [options[fallbackIndex]];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment