Skip to content
Merged
Show file tree
Hide file tree
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
52 changes: 51 additions & 1 deletion src/components/SelectionList/BaseSelectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import useArrowKeyFocusManager from '@hooks/useArrowKeyFocusManager';
import useDebounce from '@hooks/useDebounce';
import useKeyboardShortcut from '@hooks/useKeyboardShortcut';
import useKeyboardState from '@hooks/useKeyboardState';
import usePrevious from '@hooks/usePrevious';
import useSafeAreaPaddings from '@hooks/useSafeAreaPaddings';
import useScrollEnabled from '@hooks/useScrollEnabled';
import useSingleExecution from '@hooks/useSingleExecution';
Expand Down Expand Up @@ -288,7 +289,6 @@ function BaseSelectionList<TItem extends ListItem>({
onFocusChange={(v: boolean) => (isTextInputFocusedRef.current = v)}
showLoadingPlaceholder={showLoadingPlaceholder}
isLoadingNewOptions={isLoadingNewOptions}
setFocusedIndex={setFocusedIndex}
/>
);
};
Expand Down Expand Up @@ -392,6 +392,56 @@ function BaseSelectionList<TItem extends ListItem>({
[data.length, scrollToIndex, setFocusedIndex],
);

const prevSearchValue = usePrevious(textInputOptions?.value);
const prevSelectedOptionsLength = usePrevious(dataDetails.selectedOptions.length);
const prevAllOptionsLength = usePrevious(data.length);

useEffect(() => {
const currentSearchValue = textInputOptions?.value;
const searchChanged = prevSearchValue !== currentSearchValue;
const selectedOptionsChanged = dataDetails.selectedOptions.length !== prevSelectedOptionsLength;
// Do not change focus if:
// 1. Input value is the same or
// 2. Data length is 0 or
// 3. shouldUpdateFocusedIndex is true => other function handles the focus
if ((!searchChanged && !selectedOptionsChanged) || data.length === 0 || shouldUpdateFocusedIndex) {
return;
}

const hasSearchBeenCleared = prevSearchValue && !currentSearchValue;
if (hasSearchBeenCleared) {
const foundSelectedItemIndex = data.findIndex(isItemSelected);

if (foundSelectedItemIndex !== -1 && !canSelectMultiple) {
scrollToIndex(foundSelectedItemIndex);
setFocusedIndex(foundSelectedItemIndex);
return;
}
}

// Remove focus (set focused index to -1) if:
// 1. If the search is idle or
// 2. If the user is just toggling options without changing the list content
Comment thread
zfurtak marked this conversation as resolved.
// Otherwise (e.g. when filtering/typing), focus on the first item (0)
const isSearchIdle = !prevSearchValue && !currentSearchValue;
const newSelectedIndex = isSearchIdle || (selectedOptionsChanged && prevAllOptionsLength === data.length) ? -1 : 0;

scrollToIndex(newSelectedIndex);
setFocusedIndex(newSelectedIndex);
}, [
canSelectMultiple,
data,
dataDetails.selectedOptions.length,
isItemSelected,
prevAllOptionsLength,
prevSelectedOptionsLength,
prevSearchValue,
scrollToIndex,
setFocusedIndex,
shouldUpdateFocusedIndex,
textInputOptions?.value,
]);
Comment thread
zfurtak marked this conversation as resolved.

useEffect(() => {
if (!itemFocusTimeoutRef.current) {
return;
Expand Down
7 changes: 1 addition & 6 deletions src/components/SelectionList/components/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ type TextInputProps = {
/** Whether to show the loading indicator for new options */
isLoadingNewOptions?: boolean;

/** Function to update the focused index in the list */
setFocusedIndex: (index: number) => void;

/** Function to focus text input component */
focusTextInput: () => void;
};
Expand All @@ -64,7 +61,6 @@ function TextInput({
showLoadingPlaceholder,
isLoadingNewOptions,
shouldShowTextInput,
setFocusedIndex,
focusTextInput,
}: TextInputProps) {
const styles = useThemeStyles();
Expand All @@ -80,9 +76,8 @@ function TextInput({
const handleTextInputChange = useCallback(
(text: string) => {
onChangeText?.(text);
setFocusedIndex(0);
},
[onChangeText, setFocusedIndex],
[onChangeText],
);

useFocusEffect(
Expand Down
Loading