Some nits

This commit is contained in:
Eric Bailey
2026-04-03 16:07:28 -05:00
parent 8b65e57889
commit 12ccb3479f
2 changed files with 69 additions and 61 deletions
+22 -6
View File
@@ -48,7 +48,7 @@ import {
import {AutosizedTextarea} from '#/components/forms/AutosizedTextarea' import {AutosizedTextarea} from '#/components/forms/AutosizedTextarea'
import {useOnKeyboard} from '#/components/hooks/useOnKeyboard' import {useOnKeyboard} from '#/components/hooks/useOnKeyboard'
import {Span, Text} from '#/components/Typography' import {Span, Text} from '#/components/Typography'
import {IS_WEB, IS_WEB_TOUCH_DEVICE} from '#/env' import {IS_IOS, IS_WEB, IS_WEB_TOUCH_DEVICE} from '#/env'
export type SubmitRequest = export type SubmitRequest =
| { | {
@@ -219,11 +219,27 @@ export function Composer({
transform: [{translateY: -inputScrollSharedValue.value}], transform: [{translateY: -inputScrollSharedValue.value}],
})) }))
const textStyle = useMemo(() => { const textStyle = useMemo(() => {
return normalizeTextStyles([a.leading_snug, rawTextStyle, t.atoms.text], { const ts = normalizeTextStyles(
fontScale: fonts.scaleMultiplier, [a.leading_snug, rawTextStyle, t.atoms.text],
fontFamily: fonts.family, {
flags: {}, fontScale: fonts.scaleMultiplier,
}) fontFamily: fonts.family,
flags: {},
},
)
/**
* On iOS, having a lineHeight on the Text component causes the text to be
* vertically misaligned with the TextInput.
*
* This only seems to be an issue on iOS, and not on Android or web. It's
* possible that this is a bug in React Native's Text component on iOS,
* but in the meantime, we'll just remove the lineHeight on iOS to ensure
* the text is properly aligned.
*/
if (IS_IOS) {
delete ts.lineHeight
}
return ts
}, [rawTextStyle, fonts]) }, [rawTextStyle, fonts])
/* /*
+47 -55
View File
@@ -1,4 +1,4 @@
import {useCallback, useEffect, useMemo, useRef, useState} from 'react' import {useEffect, useMemo, useRef, useState} from 'react'
import { import {
TextInput, TextInput,
type TextInputContentSizeChangeEvent, type TextInputContentSizeChangeEvent,
@@ -19,7 +19,6 @@ export function AutosizedTextarea({
onChangeText: onChangeTextOuter, onChangeText: onChangeTextOuter,
onContentSizeChange: onContentSizeChangeOuter, onContentSizeChange: onContentSizeChangeOuter,
style, style,
...rest ...rest
}: Omit<TextInputProps, 'multiline'> & { }: Omit<TextInputProps, 'multiline'> & {
@@ -33,11 +32,14 @@ export function AutosizedTextarea({
const {theme: t, fonts} = useAlf() const {theme: t, fonts} = useAlf()
const {processedStyle, minHeight, maxHeight} = useMemo(() => { const {processedStyle, minHeight, maxHeight} = useMemo(() => {
const fs = flatten(style) const fs = flatten(style)
const ts = normalizeTextStyles([a.leading_snug, fs, t.atoms.text], { const ts = normalizeTextStyles(
fontScale: fonts.scaleMultiplier, [a.text_md, a.leading_snug, t.atoms.text, fs],
fontFamily: fonts.family, {
flags: {}, fontScale: fonts.scaleMultiplier,
}) fontFamily: fonts.family,
flags: {},
},
)
const lineHeight = ts.lineHeight || 20 const lineHeight = ts.lineHeight || 20
const padding = extractPadding(fs ?? {}) const padding = extractPadding(fs ?? {})
const verticalSpace = padding.paddingTop + padding.paddingBottom const verticalSpace = padding.paddingTop + padding.paddingBottom
@@ -50,15 +52,11 @@ export function AutosizedTextarea({
* On iOS, minHeight/maxHeight works fine natively. * On iOS, minHeight/maxHeight works fine natively.
*/ */
const tas = IS_WEB const tas = IS_WEB
? {height: lineHeight + verticalSpace} ? {height: mh}
: IS_ANDROID : IS_ANDROID
? {height: mh} ? {height: mh}
: {minHeight: mh, maxHeight: xh} : {minHeight: mh, maxHeight: xh}
if (IS_IOS) {
delete ts.lineHeight
}
return { return {
processedStyle: { processedStyle: {
...ts, ...ts,
@@ -78,52 +76,46 @@ export function AutosizedTextarea({
const [androidInputHeight, setAndroidInputHeight] = useState(minHeight) const [androidInputHeight, setAndroidInputHeight] = useState(minHeight)
const prevHeight = useRef(0) const prevHeight = useRef(0)
const onChangeText = useCallback( const onChangeText = (text: string) => {
(text: string) => { if (IS_WEB) {
if (IS_WEB) { const el = textInputRef.current as unknown as HTMLTextAreaElement
const el = textInputRef.current as unknown as HTMLTextAreaElement if (el) {
if (el) { el.style.height = '0px'
el.style.height = '0px' const scrollHeight = el.scrollHeight
const scrollHeight = el.scrollHeight const nextHeight = Math.min(
const nextHeight = Math.min( Math.max(scrollHeight, minHeight),
Math.max(scrollHeight, minHeight), maxHeight,
maxHeight, )
) el.style.height = `${nextHeight}px`
el.style.height = `${nextHeight}px` el.style.overflowY = scrollHeight > maxHeight ? 'auto' : 'hidden'
el.style.overflowY = scrollHeight > maxHeight ? 'auto' : 'hidden' if (nextHeight !== prevHeight.current) {
if (nextHeight !== prevHeight.current) { prevHeight.current = nextHeight
prevHeight.current = nextHeight onUpdateHeight?.(nextHeight)
onUpdateHeight?.(nextHeight)
}
}
} else if (IS_IOS) {
textInputRef.current?.measure((_x, _y, _w, h) => {
if (h !== prevHeight.current) {
prevHeight.current = h
onUpdateHeight?.(h)
}
})
}
onChangeTextOuter?.(text)
},
[onChangeTextOuter, minHeight, maxHeight, onUpdateHeight],
)
const onContentSizeChange = useCallback(
(e: TextInputContentSizeChangeEvent) => {
if (IS_ANDROID) {
const h = Math.ceil(e.nativeEvent.contentSize.height)
const nextHeight = Math.min(Math.max(h, minHeight), maxHeight)
if (nextHeight !== androidInputHeight) {
setAndroidInputHeight(nextHeight)
} }
} }
} else if (IS_IOS) {
textInputRef.current?.measure((_x, _y, _w, h) => {
if (h !== prevHeight.current) {
prevHeight.current = h
onUpdateHeight?.(h)
}
})
}
onContentSizeChangeOuter?.(e) onChangeTextOuter?.(text)
}, }
[onContentSizeChangeOuter, minHeight, maxHeight, androidInputHeight],
) const onContentSizeChange = (e: TextInputContentSizeChangeEvent) => {
if (IS_ANDROID) {
const h = Math.ceil(e.nativeEvent.contentSize.height)
const nextHeight = Math.min(Math.max(h, minHeight), maxHeight)
if (nextHeight !== androidInputHeight) {
setAndroidInputHeight(nextHeight)
}
}
onContentSizeChangeOuter?.(e)
}
/* /*
* On Android, height is driven by onContentSizeChange (see the TextInput * On Android, height is driven by onContentSizeChange (see the TextInput