Skip to content

Commit

Permalink
fix(CustomSelect): Fix input focus on arrow click on touch device (#…
Browse files Browse the repository at this point in the history
…7816) (#7825)

На touch устройстве не работает фокус на input при клике в зоне инпута ближе к стрелочке. Фокус есть на обертке, но сам инпут фокуса не имеет и клавиатура не появляется, как при клике на сам инпут, ближе к левому краю.
Воспроизводится в симуляторе Iphone и на реальном устройстве.

Дело в том, что не во всей видимой области инпута событие клика принимает input, и чтобы это победить мы программно вызываем фокус на инпуте.

Изначально, в #6087, а конкретно в 0f45bb9 это было реализовано с помощью отложенного вызова фокуса для кнопки очистки, а потом функция с отложенным фокусом перекочевала и на остальной новый код.

Объяснялось это тем, что без таймаута фокус просто не работал при клике на clear button.
Финальный код был сложнее, чем тот, когда этот отложенный фокус был добавлен, и он уже мог работать без отложенного вызова фокуса.

Протестировал в браузере и в симуляторе Iphone.
  • Loading branch information
andrey-medvedev-vk authored Oct 24, 2024
1 parent a934760 commit 1efd6a7
Showing 1 changed file with 4 additions and 17 deletions.
21 changes: 4 additions & 17 deletions packages/vkui/src/components/CustomSelect/CustomSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -714,19 +714,6 @@ export function CustomSelect<OptionInterfaceT extends CustomSelectOptionInterfac
}, [emptyText, options, renderDropdown, renderOption]);

const selectInputRef = useExternRef(getSelectInputRef);
const focusOnInputTimerRef = React.useRef<ReturnType<typeof setTimeout>>();
const focusOnInput = React.useCallback(() => {
clearTimeout(focusOnInputTimerRef.current);

focusOnInputTimerRef.current = setTimeout(() => {
selectInputRef.current && selectInputRef.current.focus();
}, 0);
}, [selectInputRef]);
useIsomorphicLayoutEffect(function clearFocusOnInputTimer() {
return () => {
clearTimeout(focusOnInputTimerRef.current);
};
}, []);

const controlledValueSet = isControlledOutside && props.value !== '';
const uncontrolledValueSet = !isControlledOutside && nativeSelectValue !== '';
Expand All @@ -744,7 +731,7 @@ export function CustomSelect<OptionInterfaceT extends CustomSelectOptionInterfac
onClick={function clearSelectState() {
setNativeSelectValue('');
setInputValue('');
focusOnInput();
selectInputRef.current && selectInputRef.current.focus();
}}
disabled={restProps.disabled}
data-testid={clearButtonTestId}
Expand All @@ -756,7 +743,7 @@ export function CustomSelect<OptionInterfaceT extends CustomSelectOptionInterfac
iconProp,
restProps.disabled,
clearButtonTestId,
focusOnInput,
selectInputRef,
]);

const icon = React.useMemo(() => {
Expand Down Expand Up @@ -801,11 +788,11 @@ export function CustomSelect<OptionInterfaceT extends CustomSelectOptionInterfac

const inputIsNotFocused = document.activeElement !== selectInputRef.current;
if (inputIsNotFocused) {
focusOnInput();
selectInputRef.current.focus();
}
}
},
[document, focusOnInput, selectInputRef],
[document, selectInputRef],
);

const preventInputBlurWhenClickInsideFocusedSelectArea = (
Expand Down

0 comments on commit 1efd6a7

Please sign in to comment.