diff --git a/src/components/TextInput/BaseTextInput/index.native.tsx b/src/components/TextInput/BaseTextInput/index.native.tsx index 847600d64644..871ab8b25ac2 100644 --- a/src/components/TextInput/BaseTextInput/index.native.tsx +++ b/src/components/TextInput/BaseTextInput/index.native.tsx @@ -72,6 +72,7 @@ function BaseTextInput( ref: ForwardedRef, ) { const InputComponent = isMarkdownEnabled ? RNMarkdownTextInput : RNTextInput; + const isAutoGrowHeightMarkdown = isMarkdownEnabled && autoGrowHeight; const inputProps = {shouldSaveDraft: false, shouldUseDefaultValue: false, ...props}; const theme = useTheme(); @@ -274,7 +275,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 89f26330f859..09b644c8e76a 100644 --- a/src/components/TextInput/BaseTextInput/index.tsx +++ b/src/components/TextInput/BaseTextInput/index.tsx @@ -78,6 +78,7 @@ function BaseTextInput( ref: ForwardedRef, ) { const InputComponent = isMarkdownEnabled ? RNMarkdownTextInput : RNTextInput; + const isAutoGrowHeightMarkdown = isMarkdownEnabled && autoGrowHeight; const theme = useTheme(); const styles = useThemeStyles(); @@ -97,6 +98,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); @@ -300,7 +302,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 b4d4b7ca5ecd..ef0d33a5d2a5 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 82d33a471d9c..65faa941866a 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -1250,6 +1250,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 */