Fix iOS message input height after sending (#11533)

This commit is contained in:
Samuel Newman
2026-08-25 03:28:56 +03:00
committed by GitHub
parent 6b35d3de1c
commit 95f5360012
+13 -12
View File
@@ -8,7 +8,7 @@ import {
import {mergeRefs} from '#/lib/merge-refs' import {mergeRefs} from '#/lib/merge-refs'
import {atoms as a, extractPadding, useAlf, web} from '#/alf' import {atoms as a, extractPadding, useAlf, web} from '#/alf'
import {normalizeTextStyles} from '#/alf/typography' import {normalizeTextStyles} from '#/alf/typography'
import {IS_ANDROID, IS_IOS, IS_WEB} from '#/env' import {IS_ANDROID, IS_IOS, IS_NATIVE, IS_WEB} from '#/env'
export type AutosizedTextareaProps = Omit<TextInputProps, 'multiline'> & { export type AutosizedTextareaProps = Omit<TextInputProps, 'multiline'> & {
ref?: React.Ref<TextInput> ref?: React.Ref<TextInput>
@@ -18,13 +18,14 @@ export type AutosizedTextareaProps = Omit<TextInputProps, 'multiline'> & {
onUpdateHeight?: (height: number) => void onUpdateHeight?: (height: number) => void
/** /**
* In some cases, like on native, we may not pass in an actual `value` prop. * In some cases, like on native, we may not pass in an actual `value` prop.
* This prop allows Android to know if the field was cleared and thereby * This prop allows native platforms to know if the field was cleared and
* reset its height. This is a small hack required because we need to * thereby reset its height. This is a small hack required because Android's
* explicitly set the `{height: nativeHeight}` on Android. * height is driven by state, while iOS needs an explicit minimum height when
* cleared programmatically.
* *
* If you notice height calcuation issues after clearing the field on * If you notice height calculation issues after clearing the field on a
* Android, check if this value is being populated and cleared properly in * native platform, check if this value is being populated and cleared
* the parent component. * properly in the parent component.
*/ */
rawValue?: string rawValue?: string
} }
@@ -137,13 +138,12 @@ export function AutosizedTextarea({
} }
/* /*
* Manual height clearing required for Android because we're forced to set * Reset native height state after a programmatic clear. Android uses it as
* `{height: nativeHeight}` on Android, and even though `onContentSizeChange` * the explicit input height, while iOS uses it to decide when to scroll.
* fires, the height matches the existing height and we aren't able to reset.
*/ */
const prevRawValue = useRef(rawValue || '') const prevRawValue = useRef(rawValue || '')
useEffect(() => { useEffect(() => {
if (!IS_ANDROID) return // everything else is fine if (!IS_NATIVE) return
if (rawValue === undefined) return // uncontrolled if (rawValue === undefined) return // uncontrolled
if (prevRawValue.current?.length && rawValue === '') { if (prevRawValue.current?.length && rawValue === '') {
setNativeHeight(minInputHeight) setNativeHeight(minInputHeight)
@@ -176,7 +176,8 @@ export function AutosizedTextarea({
wordBreak: 'break-word', wordBreak: 'break-word',
}), }),
style, style,
IS_ANDROID ? {height: nativeHeight} : {}, IS_ANDROID && {height: nativeHeight},
IS_IOS && rawValue === '' && {height: minInputHeight},
]} ]}
{...rest} {...rest}
ref={mergeRefs([ ref={mergeRefs([