From f8cfdd5e0a8321434431a730d0ce119ceacb1f6d Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Mon, 24 Aug 2026 15:07:45 +0100 Subject: [PATCH] fix ios message input height reset --- src/components/forms/AutosizedTextarea.tsx | 25 +++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/components/forms/AutosizedTextarea.tsx b/src/components/forms/AutosizedTextarea.tsx index d81265f4da..414bdecda7 100644 --- a/src/components/forms/AutosizedTextarea.tsx +++ b/src/components/forms/AutosizedTextarea.tsx @@ -8,7 +8,7 @@ import { import {mergeRefs} from '#/lib/merge-refs' import {atoms as a, extractPadding, useAlf, web} from '#/alf' 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 & { ref?: React.Ref @@ -18,13 +18,14 @@ export type AutosizedTextareaProps = Omit & { onUpdateHeight?: (height: number) => void /** * 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 - * reset its height. This is a small hack required because we need to - * explicitly set the `{height: nativeHeight}` on Android. + * This prop allows native platforms to know if the field was cleared and + * thereby reset its height. This is a small hack required because Android's + * 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 - * Android, check if this value is being populated and cleared properly in - * the parent component. + * If you notice height calculation issues after clearing the field on a + * native platform, check if this value is being populated and cleared + * properly in the parent component. */ rawValue?: string } @@ -137,13 +138,12 @@ export function AutosizedTextarea({ } /* - * Manual height clearing required for Android because we're forced to set - * `{height: nativeHeight}` on Android, and even though `onContentSizeChange` - * fires, the height matches the existing height and we aren't able to reset. + * Reset native height state after a programmatic clear. Android uses it as + * the explicit input height, while iOS uses it to decide when to scroll. */ const prevRawValue = useRef(rawValue || '') useEffect(() => { - if (!IS_ANDROID) return // everything else is fine + if (!IS_NATIVE) return if (rawValue === undefined) return // uncontrolled if (prevRawValue.current?.length && rawValue === '') { setNativeHeight(minInputHeight) @@ -176,7 +176,8 @@ export function AutosizedTextarea({ wordBreak: 'break-word', }), style, - IS_ANDROID ? {height: nativeHeight} : {}, + IS_ANDROID && {height: nativeHeight}, + IS_IOS && rawValue === '' && {height: minInputHeight}, ]} {...rest} ref={mergeRefs([