From ea552662a0525452cf2827c3296e156b709769bf Mon Sep 17 00:00:00 2001 From: Mateusz Titz Date: Thu, 16 Jan 2025 10:16:26 +0100 Subject: [PATCH 1/3] Simplify single line TextInput styling to allow for different heights --- .../TextInput/BaseTextInput/index.native.tsx | 7 ++++- .../TextInput/BaseTextInput/index.tsx | 28 +------------------ src/styles/index.ts | 2 -- 3 files changed, 7 insertions(+), 30 deletions(-) diff --git a/src/components/TextInput/BaseTextInput/index.native.tsx b/src/components/TextInput/BaseTextInput/index.native.tsx index b69fb7779177..3b97caf7dc90 100644 --- a/src/components/TextInput/BaseTextInput/index.native.tsx +++ b/src/components/TextInput/BaseTextInput/index.native.tsx @@ -266,6 +266,9 @@ function BaseTextInput( const inputPaddingLeft = !!prefixCharacter && StyleUtils.getPaddingLeft(StyleUtils.getCharacterPadding(prefixCharacter) + styles.pl1.paddingLeft); const inputPaddingRight = !!suffixCharacter && StyleUtils.getPaddingRight(StyleUtils.getCharacterPadding(suffixCharacter) + styles.pr1.paddingRight); + + // Height fix is needed only for Text single line inputs + const shouldApplyHeight = !isMultiline && !isMarkdownEnabled; return ( <> @@ -356,7 +359,9 @@ function BaseTextInput( inputPaddingRight, inputProps.secureTextEntry && styles.secureInput, - !isMultiline && {height, lineHeight: undefined}, + // Explicitly remove `lineHeight` from single line inputs so that long text doesn't disappear + // once it exceeds the input space on iOS (See https://github.com/Expensify/App/issues/13802) + shouldApplyHeight && {height, lineHeight: undefined}, // Stop scrollbar flashing when breaking lines with autoGrowHeight enabled. ...(autoGrowHeight && !isAutoGrowHeightMarkdown diff --git a/src/components/TextInput/BaseTextInput/index.tsx b/src/components/TextInput/BaseTextInput/index.tsx index 45aa868ad219..1842ef4948ba 100644 --- a/src/components/TextInput/BaseTextInput/index.tsx +++ b/src/components/TextInput/BaseTextInput/index.tsx @@ -1,6 +1,6 @@ import {Str} from 'expensify-common'; import type {ForwardedRef, MutableRefObject} from 'react'; -import React, {forwardRef, useCallback, useEffect, useMemo, useRef, useState} from 'react'; +import React, {forwardRef, useCallback, useEffect, useRef, useState} from 'react'; import type {GestureResponderEvent, LayoutChangeEvent, NativeSyntheticEvent, StyleProp, TextInput, TextInputFocusEventData, ViewStyle} from 'react-native'; import {ActivityIndicator, StyleSheet, View} from 'react-native'; import {useSharedValue, withSpring} from 'react-native-reanimated'; @@ -98,7 +98,6 @@ function BaseTextInput( const [passwordHidden, setPasswordHidden] = useState(inputProps.secureTextEntry); const [textInputWidth, setTextInputWidth] = useState(0); const [textInputHeight, setTextInputHeight] = useState(0); - const [height, setHeight] = useState(variables.componentSizeLarge); const [width, setWidth] = useState(null); const labelScale = useSharedValue(initialActiveLabel ? styleConst.ACTIVE_LABEL_SCALE : styleConst.INACTIVE_LABEL_SCALE); @@ -187,7 +186,6 @@ function BaseTextInput( const layout = event.nativeEvent.layout; setWidth((prevWidth: number | null) => (autoGrowHeight ? layout.width : prevWidth)); - setHeight((prevHeight: number) => (!multiline ? layout.height : prevHeight)); }, [autoGrowHeight, multiline], ); @@ -263,25 +261,6 @@ function BaseTextInput( ]); const isMultiline = multiline || autoGrowHeight; - /** - * To prevent text jumping caused by virtual DOM calculations on Safari and mobile Chrome, - * make sure to include the `lineHeight`. - * Reference: https://github.com/Expensify/App/issues/26735 - * For other platforms, explicitly remove `lineHeight` from single-line inputs - * to prevent long text from disappearing once it exceeds the input space. - * See https://github.com/Expensify/App/issues/13802 - */ - const lineHeight = useMemo(() => { - if (Browser.isSafari() || Browser.isMobileChrome()) { - const lineHeightValue = StyleSheet.flatten(inputStyle).lineHeight; - if (lineHeightValue !== undefined) { - return lineHeightValue; - } - } - - return undefined; - }, [inputStyle]); - const inputPaddingLeft = !!prefixCharacter && StyleUtils.getPaddingLeft(StyleUtils.getCharacterPadding(prefixCharacter) + styles.pl1.paddingLeft); const inputPaddingRight = !!suffixCharacter && StyleUtils.getPaddingRight(StyleUtils.getCharacterPadding(suffixCharacter) + styles.pr1.paddingRight); @@ -330,7 +309,6 @@ function BaseTextInput( /> ) : null} - {!!iconLeft && ( @@ -380,10 +358,6 @@ function BaseTextInput( inputPaddingRight, inputProps.secureTextEntry && styles.secureInput, - // Explicitly remove `lineHeight` from single line inputs so that long text doesn't disappear - // once it exceeds the input space (See https://github.com/Expensify/App/issues/13802) - !isMultiline && {height, lineHeight}, - // Explicitly change boxSizing attribute for mobile chrome in order to apply line-height // for the issue mentioned here https://github.com/Expensify/App/issues/26735 // Set overflow property to enable the parent flexbox to shrink its size diff --git a/src/styles/index.ts b/src/styles/index.ts index 06feb42b3fe2..cb5020628329 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -1247,8 +1247,6 @@ const styles = (theme: ThemeColors) => }, textInputAndIconContainer: { - flex: 1, - height: '100%', zIndex: -1, flexDirection: 'row', }, From 04c80f6a6a0bf503a427daa1ca42bb399d33358b Mon Sep 17 00:00:00 2001 From: Mateusz Titz Date: Thu, 16 Jan 2025 16:09:14 +0100 Subject: [PATCH 2/3] Fix new lint rules --- src/components/TextInput/BaseTextInput/index.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/TextInput/BaseTextInput/index.tsx b/src/components/TextInput/BaseTextInput/index.tsx index 1842ef4948ba..da87a34d47eb 100644 --- a/src/components/TextInput/BaseTextInput/index.tsx +++ b/src/components/TextInput/BaseTextInput/index.tsx @@ -24,8 +24,8 @@ import useMarkdownStyle from '@hooks/useMarkdownStyle'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as Browser from '@libs/Browser'; -import * as InputUtils from '@libs/InputUtils'; +import {isMobileChrome, isMobileSafari, isSafari} from '@libs/Browser'; +import {scrollToRight} from '@libs/InputUtils'; import isInputAutoFilled from '@libs/isInputAutoFilled'; import variables from '@styles/variables'; import CONST from '@src/CONST'; @@ -362,7 +362,7 @@ function BaseTextInput( // for the issue mentioned here https://github.com/Expensify/App/issues/26735 // Set overflow property to enable the parent flexbox to shrink its size // (See https://github.com/Expensify/App/issues/41766) - !isMultiline && Browser.isMobileChrome() && {boxSizing: 'content-box', height: undefined, ...styles.overflowAuto}, + !isMultiline && isMobileChrome() && {boxSizing: 'content-box', height: undefined, ...styles.overflowAuto}, // Stop scrollbar flashing when breaking lines with autoGrowHeight enabled. ...(autoGrowHeight && !isAutoGrowHeightMarkdown @@ -405,7 +405,7 @@ function BaseTextInput( if (didScrollToEndRef.current || !input.current) { return; } - InputUtils.scrollToRight(input.current); + scrollToRight(input.current); didScrollToEndRef.current = true; }} > @@ -498,7 +498,7 @@ function BaseTextInput( return; } let additionalWidth = 0; - if (Browser.isMobileSafari() || Browser.isSafari() || Browser.isMobileChrome()) { + if (isMobileSafari() || isSafari() || isMobileChrome()) { additionalWidth = 2; } setTextInputWidth(e.nativeEvent.layout.width + additionalWidth); From 27e039d4d5618ed6cac87eaa695b8c93b5f03303 Mon Sep 17 00:00:00 2001 From: Mateusz Titz Date: Wed, 22 Jan 2025 10:45:19 +0100 Subject: [PATCH 3/3] apply height style only to multiline TextInput --- src/styles/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/styles/index.ts b/src/styles/index.ts index cb5020628329..62497df018c5 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -1243,6 +1243,7 @@ const styles = (theme: ThemeColors) => }, textInputMultilineContainer: { + height: '100%', paddingTop: 23, },