diff --git a/src/components/TextInput/BaseTextInput/index.native.tsx b/src/components/TextInput/BaseTextInput/index.native.tsx index a03e9dbb9aa2..4b76dca5cc53 100644 --- a/src/components/TextInput/BaseTextInput/index.native.tsx +++ b/src/components/TextInput/BaseTextInput/index.native.tsx @@ -71,6 +71,7 @@ function BaseTextInput( ref: ForwardedRef, ) { const InputComponent = isMarkdownEnabled ? RNMarkdownTextInput : RNTextInput; + const isAutoGrowHeightMarkdown = isMarkdownEnabled && autoGrowHeight; const inputProps = {shouldSaveDraft: false, shouldUseDefaultValue: false, ...props}; const theme = useTheme(); @@ -273,7 +274,10 @@ function BaseTextInput( onLayout={onLayout} accessibilityLabel={label} style={[ - autoGrowHeight && styles.autoGrowHeightInputContainer(textInputHeight, variables.componentSizeLarge, typeof maxAutoGrowHeight === 'number' ? maxAutoGrowHeight : 0), + autoGrowHeight && + !isAutoGrowHeightMarkdown && + styles.autoGrowHeightInputContainer(textInputHeight, variables.componentSizeLarge, typeof maxAutoGrowHeight === 'number' ? maxAutoGrowHeight : 0), + isAutoGrowHeightMarkdown && {minHeight: variables.componentSizeLarge}, !isMultiline && styles.componentHeightLarge, touchableInputWrapperStyle, ]} @@ -351,9 +355,10 @@ function BaseTextInput( !isMultiline && {height, lineHeight: undefined}, // Stop scrollbar flashing when breaking lines with autoGrowHeight enabled. - ...(autoGrowHeight + ...(autoGrowHeight && !isAutoGrowHeightMarkdown ? [StyleUtils.getAutoGrowHeightInputStyle(textInputHeight, typeof maxAutoGrowHeight === 'number' ? maxAutoGrowHeight : 0), styles.verticalAlignTop] : []), + isAutoGrowHeightMarkdown ? [StyleUtils.getMarkdownMaxHeight(maxAutoGrowHeight), styles.verticalAlignTop] : undefined, // Add disabled color theme when field is not editable. inputProps.disabled && styles.textInputDisabled, styles.pointerEventsAuto, @@ -444,7 +449,7 @@ function BaseTextInput( This text view is used to calculate width or height of the input value given textStyle in this component. This Text component is intentionally positioned out of the screen. */} - {(!!autoGrow || autoGrowHeight) && ( + {(!!autoGrow || autoGrowHeight) && !isAutoGrowHeightMarkdown && ( // Add +2 to width on Safari browsers so that text is not cut off due to the cursor or when changing the value // https://github.com/Expensify/App/issues/8158 // https://github.com/Expensify/App/issues/26628 diff --git a/src/components/TextInput/BaseTextInput/index.tsx b/src/components/TextInput/BaseTextInput/index.tsx index bfc3ab213dd0..0e42700bc5fa 100644 --- a/src/components/TextInput/BaseTextInput/index.tsx +++ b/src/components/TextInput/BaseTextInput/index.tsx @@ -77,6 +77,7 @@ function BaseTextInput( ref: ForwardedRef, ) { const InputComponent = isMarkdownEnabled ? RNMarkdownTextInput : RNTextInput; + const isAutoGrowHeightMarkdown = isMarkdownEnabled && autoGrowHeight; const theme = useTheme(); const styles = useThemeStyles(); @@ -96,6 +97,7 @@ function BaseTextInput( const [textInputHeight, setTextInputHeight] = useState(0); const [height, setHeight] = useState(variables.componentSizeLarge); const [width, setWidth] = useState(null); + const labelScale = useRef(new Animated.Value(initialActiveLabel ? styleConst.ACTIVE_LABEL_SCALE : styleConst.INACTIVE_LABEL_SCALE)).current; const labelTranslateY = useRef(new Animated.Value(initialActiveLabel ? styleConst.ACTIVE_LABEL_TRANSLATE_Y : styleConst.INACTIVE_LABEL_TRANSLATE_Y)).current; const input = useRef(null); @@ -299,7 +301,10 @@ function BaseTextInput( // or if multiline is not supplied we calculate the textinput height, using onLayout. onLayout={onLayout} style={[ - autoGrowHeight && styles.autoGrowHeightInputContainer(textInputHeight, variables.componentSizeLarge, typeof maxAutoGrowHeight === 'number' ? maxAutoGrowHeight : 0), + autoGrowHeight && + !isAutoGrowHeightMarkdown && + styles.autoGrowHeightInputContainer(textInputHeight, variables.componentSizeLarge, typeof maxAutoGrowHeight === 'number' ? maxAutoGrowHeight : 0), + isAutoGrowHeightMarkdown && {minHeight: variables.componentSizeLarge}, !isMultiline && styles.componentHeightLarge, touchableInputWrapperStyle, ]} @@ -326,6 +331,7 @@ function BaseTextInput( /> ) : null} + {iconLeft && ( @@ -386,10 +392,10 @@ function BaseTextInput( !isMultiline && Browser.isMobileChrome() && {boxSizing: 'content-box', height: undefined, ...styles.overflowAuto}, // Stop scrollbar flashing when breaking lines with autoGrowHeight enabled. - ...(autoGrowHeight + ...(autoGrowHeight && !isAutoGrowHeightMarkdown ? [StyleUtils.getAutoGrowHeightInputStyle(textInputHeight, typeof maxAutoGrowHeight === 'number' ? maxAutoGrowHeight : 0), styles.verticalAlignTop] : []), - + isAutoGrowHeightMarkdown ? [StyleUtils.getMarkdownMaxHeight(maxAutoGrowHeight), styles.verticalAlignTop] : undefined, // Add disabled color theme when field is not editable. inputProps.disabled && shouldUseDisabledStyles && styles.textInputDisabled, styles.pointerEventsAuto, @@ -490,7 +496,7 @@ function BaseTextInput( This text view is used to calculate width or height of the input value given textStyle in this component. This Text component is intentionally positioned out of the screen. */} - {(!!autoGrow || autoGrowHeight) && ( + {(!!autoGrow || autoGrowHeight) && !isAutoGrowHeightMarkdown && ( // Add +2 to width on Safari browsers so that text is not cut off due to the cursor or when changing the value // Reference: https://github.com/Expensify/App/issues/8158, https://github.com/Expensify/App/issues/26628 // For mobile Chrome, ensure proper display of the text selection handle (blue bubble down). diff --git a/src/styles/index.ts b/src/styles/index.ts index 33b39ac5fa82..0904d34efe2b 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -1181,6 +1181,7 @@ const styles = (theme: ThemeColors) => overflow: 'hidden', borderBottomWidth: 2, borderColor: theme.border, + paddingBottom: 8, }, optionRowAmountInput: { diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index c7665fc1e3dd..1e44155330a9 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1249,6 +1249,15 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({ }; }, + /* + * Returns the actual maxHeight of the auto-growing markdown text input. + */ + getMarkdownMaxHeight: (maxAutoGrowHeight: number | undefined): TextStyle => { + // maxHeight is not of the input only but the of the whole input container + // which also includes the top padding and bottom border + return maxAutoGrowHeight ? {maxHeight: maxAutoGrowHeight - styles.textInputMultilineContainer.paddingTop - styles.textInputContainer.borderBottomWidth} : {}; + }, + /** * Return the style from an avatar size constant */