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

Fix caret is shown at right side of search input for a moment #52611

Closed
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
1 change: 0 additions & 1 deletion src/components/Search/SearchPageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ function HeaderWrapper({icon, children, text, value, isCannedQuery, onSubmit, se
value={value}
onSubmit={onSubmit}
updateSearch={setValue}
autoFocus={false}
isFullWidth
wrapperStyle={[styles.searchRouterInputResults, styles.br2]}
wrapperFocusedStyle={styles.searchRouterInputResultsFocused}
Expand Down
3 changes: 3 additions & 0 deletions src/components/Search/SearchRouter/SearchRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {useOptionsList} from '@components/OptionListContextProvider';
import type {SearchAutocompleteQueryRange, SearchQueryString} from '@components/Search/types';
import type {SelectionListHandle} from '@components/SelectionList/types';
import useActiveWorkspace from '@hooks/useActiveWorkspace';
import useAutoFocusInput from '@hooks/useAutoFocusInput';
import useDebouncedState from '@hooks/useDebouncedState';
import useKeyboardShortcut from '@hooks/useKeyboardShortcut';
import useLocalize from '@hooks/useLocalize';
Expand Down Expand Up @@ -54,6 +55,7 @@ function SearchRouter({onRouterClose}: SearchRouterProps) {
const [betas] = useOnyx(ONYXKEYS.BETAS);
const [recentSearches] = useOnyx(ONYXKEYS.RECENT_SEARCHES);
const [isSearchingForReports] = useOnyx(ONYXKEYS.IS_SEARCHING_FOR_REPORTS, {initWithStoredValues: false});
const {inputCallbackRef} = useAutoFocusInput();
const [autocompleteSuggestions, setAutocompleteSuggestions] = useState<AutocompleteItemData[] | undefined>([]);
const [autocompleteSubstitutions, setAutocompleteSubstitutions] = useState<SubstitutionMap>({});

Expand Down Expand Up @@ -390,6 +392,7 @@ function SearchRouter({onRouterClose}: SearchRouterProps) {
/>
)}
<SearchRouterInput
ref={inputCallbackRef}
value={textInputValue}
isFullWidth={shouldUseNarrowLayout}
updateSearch={onSearchChange}
Expand Down
46 changes: 22 additions & 24 deletions src/components/Search/SearchRouter/SearchRouterInput.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type {ReactNode, RefObject} from 'react';
import React, {useState} from 'react';
import type {ForwardedRef, ReactNode, RefObject} from 'react';
import React, {forwardRef, useState} from 'react';
import type {StyleProp, ViewStyle} from 'react-native';
import {View} from 'react-native';
import FormHelpMessage from '@components/FormHelpMessage';
import type {SelectionListHandle} from '@components/SelectionList/types';
import TextInput from '@components/TextInput';
import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useThemeStyles from '@hooks/useThemeStyles';
import shouldDelayFocus from '@libs/shouldDelayFocus';
import variables from '@styles/variables';
import CONST from '@src/CONST';

Expand All @@ -34,9 +34,6 @@ type SearchRouterInputProps = {
/** Whether the offline message should be shown */
shouldShowOfflineMessage?: boolean;

/** Whether the input should be focused */
autoFocus?: boolean;

/** Any additional styles to apply */
wrapperStyle?: StyleProp<ViewStyle>;

Expand All @@ -53,21 +50,23 @@ type SearchRouterInputProps = {
isSearchingForReports?: boolean;
};

function SearchRouterInput({
value,
updateSearch,
onSubmit = () => {},
routerListRef,
isFullWidth,
disabled = false,
shouldShowOfflineMessage = false,
autoFocus = true,
wrapperStyle,
wrapperFocusedStyle,
outerWrapperStyle,
rightComponent,
isSearchingForReports,
}: SearchRouterInputProps) {
function SearchRouterInput(
{
value,
updateSearch,
onSubmit = () => {},
routerListRef,
isFullWidth,
disabled = false,
shouldShowOfflineMessage = false,
wrapperStyle,
wrapperFocusedStyle,
outerWrapperStyle,
rightComponent,
isSearchingForReports,
}: SearchRouterInputProps,
ref: ForwardedRef<BaseTextInputRef>,
) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const [isFocused, setIsFocused] = useState<boolean>(false);
Expand All @@ -81,11 +80,10 @@ function SearchRouterInput({
<View style={[styles.flexRow, styles.alignItemsCenter, wrapperStyle ?? styles.searchRouterTextInputContainer, isFocused && wrapperFocusedStyle]}>
<View style={styles.flex1}>
<TextInput
ref={ref}
testID="search-router-text-input"
value={value}
onChangeText={updateSearch}
autoFocus={autoFocus}
shouldDelayFocus={shouldDelayFocus}
loadingSpinnerStyle={[styles.mt0, styles.mr2]}
role={CONST.ROLE.PRESENTATION}
placeholder={translate('search.searchPlaceholder')}
Expand Down Expand Up @@ -123,4 +121,4 @@ function SearchRouterInput({

SearchRouterInput.displayName = 'SearchRouterInput';

export default SearchRouterInput;
export default forwardRef(SearchRouterInput);
3 changes: 2 additions & 1 deletion src/components/TextInput/BaseTextInput/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {MarkdownStyle} from '@expensify/react-native-live-markdown';
import type {GestureResponderEvent, StyleProp, TextInputProps, TextStyle, ViewStyle} from 'react-native';
import type {AnimatedMarkdownTextInputRef} from '@components/RNMarkdownTextInput';
import type {AnimatedTextInputRef} from '@components/RNTextInput';
import type IconAsset from '@src/types/utils/IconAsset';

Expand Down Expand Up @@ -144,7 +145,7 @@ type CustomBaseTextInputProps = {
contentWidth?: number;
};

type BaseTextInputRef = HTMLFormElement | AnimatedTextInputRef;
type BaseTextInputRef = HTMLFormElement | AnimatedTextInputRef | AnimatedMarkdownTextInputRef;

type BaseTextInputProps = CustomBaseTextInputProps & TextInputProps;

Expand Down
4 changes: 2 additions & 2 deletions src/components/TimePicker/TimePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ function TimePicker({defaultValue = '', onSubmit, onInputChange = () => {}, shou
updateRefs('minuteRef', textInputRef);
minuteInputRef.current = textInputRef as TextInput | null;
if (!showFullFormat) {
inputCallbackRef(textInputRef as TextInput | null);
inputCallbackRef(textInputRef);
}
}}
onSelectionChange={(e) => {
Expand Down Expand Up @@ -806,7 +806,7 @@ function TimePicker({defaultValue = '', onSubmit, onInputChange = () => {}, shou
updateRefs('milisecondRef', textInputRef);
milisecondInputRef.current = textInputRef as TextInput | null;
if (showFullFormat) {
inputCallbackRef(textInputRef as TextInput | null);
inputCallbackRef(textInputRef);
}
}}
onSelectionChange={(e) => {
Expand Down
10 changes: 5 additions & 5 deletions src/hooks/useAutoFocusInput.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import {useFocusEffect} from '@react-navigation/native';
import {useCallback, useEffect, useRef, useState} from 'react';
import type {RefObject} from 'react';
import type {TextInput} from 'react-native';
import {InteractionManager} from 'react-native';
import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types';
import {moveSelectionToEnd, scrollToBottom} from '@libs/InputUtils';
import CONST from '@src/CONST';
import {useSplashScreenStateContext} from '@src/SplashScreenStateContext';

type UseAutoFocusInput = {
inputCallbackRef: (ref: TextInput | null) => void;
inputRef: RefObject<TextInput | null>;
inputCallbackRef: (ref: BaseTextInputRef | null) => void;
inputRef: RefObject<BaseTextInputRef | null>;
};

export default function useAutoFocusInput(isMultiline = false): UseAutoFocusInput {
Expand All @@ -18,7 +18,7 @@ export default function useAutoFocusInput(isMultiline = false): UseAutoFocusInpu

const {splashScreenState} = useSplashScreenStateContext();

const inputRef = useRef<TextInput | null>(null);
const inputRef = useRef<BaseTextInputRef | null>(null);
const focusTimeoutRef = useRef<NodeJS.Timeout | null>(null);

useEffect(() => {
Expand Down Expand Up @@ -53,7 +53,7 @@ export default function useAutoFocusInput(isMultiline = false): UseAutoFocusInpu
}, []),
);

const inputCallbackRef = (ref: TextInput | null) => {
const inputCallbackRef = (ref: BaseTextInputRef | null) => {
inputRef.current = ref;
if (isInputInitialized) {
return;
Expand Down
5 changes: 3 additions & 2 deletions src/libs/InputUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ const moveSelectionToEnd: MoveSelectiontoEnd = (input) => {
if (!('setSelectionRange' in input)) {
return;
}
const length = input.value.length;
input.setSelectionRange(length, length);
const inputElement = input as HTMLInputElement;
const length = inputElement.value.length;
inputElement.setSelectionRange(length, length);
};

export {scrollToBottom, moveSelectionToEnd};
6 changes: 3 additions & 3 deletions src/libs/InputUtils/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {TextInput} from 'react-native';
import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types';

type ScrollToBottom = (input: HTMLInputElement | TextInput) => void;
type MoveSelectiontoEnd = (input: HTMLInputElement | TextInput) => void;
type ScrollToBottom = (input: BaseTextInputRef) => void;
type MoveSelectiontoEnd = (input: BaseTextInputRef) => void;

export type {ScrollToBottom, MoveSelectiontoEnd};
Loading