Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions src/components/TextInput/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@ export type OutlinedTextInputHookData = SharedTextInputStyleData & {
};

export type TextInputLayoutData =
| FilledTextInputHookData
| OutlinedTextInputHookData;
FilledTextInputHookData | OutlinedTextInputHookData;

export type TextInputLayoutState = Omit<
TextInputLayoutData,
Expand All @@ -145,8 +144,7 @@ export type TextInputHookReturn = SharedTextInputStyleData & {
selectionColor: ColorValue;
cursorColor: ColorValue;
animatedActiveOutlineStyles:
| StyleProp<AnimatedStyle<StyleProp<ViewStyle>>>
| undefined;
StyleProp<AnimatedStyle<StyleProp<ViewStyle>>> | undefined;
animatedContainerStyle: StyleProp<AnimatedStyle<StyleProp<ViewStyle>>>;
animatedLabelWrapperStyles: StyleProp<AnimatedStyle<StyleProp<ViewStyle>>>;
containerStyles: StyleProp<ViewStyle>;
Expand All @@ -158,11 +156,9 @@ export type TextInputHookReturn = SharedTextInputStyleData & {
counterText: string;
accessibilityProps: GetAccessibilityDataReturn;
renderLeadingAccessory:
| ((props: TextInputAccessoryProps) => React.ReactNode)
| undefined;
((props: TextInputAccessoryProps) => React.ReactNode) | undefined;
renderTrailingAccessory:
| ((props: TextInputAccessoryProps) => React.ReactNode)
| undefined;
((props: TextInputAccessoryProps) => React.ReactNode) | undefined;
onChangeText: (text: string) => void;
onFocus: (e: FocusEvent) => void;
onBlur: (e: BlurEvent) => void;
Expand Down Expand Up @@ -360,7 +356,12 @@ function TextInput({
});

return (
<Pressable onPress={focusInput} accessible={false} role="none">
<Pressable
onPress={focusInput}
accessible={false}
role="none"
style={styles.root}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't reproduce horizontal blowout this fixes.
On iPhone 16 Pro simulator, TextInput inside flexDirection: 'row' parent produces 0% differing pixels between main & this branch - with long value, with/without label and with 100/300pt width constraint. The root stays ~32pt wide & sibling is never pushed out

Image

Also worth checking whether this is still reproducible: #4790 was opened before TextInput rewrite in #4909 and it has no runnable repro.
so may I ask you to share repro (lib version + platform) you're seeing this on?

>
<View style={fieldStyles}>
{/* Disabled tint overlay — filled variant only. A childless
absolutely-positioned View whose translucent fill is applied via the
Expand Down
3 changes: 3 additions & 0 deletions src/components/TextInput/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import { tokens } from '../../theme/tokens';
const { bodyLarge, bodySmall } = tokens.md.sys.typescale;

export const styles = StyleSheet.create({
root: {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no way to opt out: style is destructured into inputStyleOverride (utils.ts:308 / 456) & only reaches native input (never this root).
On device, style={{ flexShrink: 0 }} changed nothing - fields still squeezed to 43pt

since this changes layout for every existing consumer, could the consumer style be merged into root so apps can override it?

flexShrink: 1,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one small concern: flexShrink applies on both axes, so in fixed-height container the vertical layout gets squeezed as well.

On iPhone 16 Pro simulator with a column of height: 90 holding 2 labelled fields + supporting text, the spacing between fields drops from 74.33pt to 43pt and 2nd field's background overlaps first by ~12pt

Image

Same pattern in card (height: 210, 3 fields): supporting-text row collapses 27.33pt -> 16.33pt and last line ends up outside the card

Image

main isn't perfect in these cases either (it overflows), but text stays readable there.
Would it be possible to keep shrinking horizontal-only? for example minWidth: 0 on the root so vertical layouts stay as they are?

},
input: {
paddingVertical: 0,
paddingHorizontal: 0,
Expand Down
15 changes: 15 additions & 0 deletions src/components/__tests__/TextInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1340,3 +1340,18 @@ it('hides prefix/suffix when blurring after clear() was called while focused', a
expect(screen.queryByText('$')).not.toBeOnTheScreen();
expect(screen.queryByText('/100')).not.toBeOnTheScreen();
});

it('applies flexShrink: 1 to the outer container to prevent overflowing constrained flex parents', async () => {
const { root } = await render(
<View style={{ width: 100, flexDirection: 'row' }}>
<TextInput
label="Constrained Input"
value="This is an extremely long string that would typically force an unconstrained flex parent to expand beyond limits"
onChangeText={() => {}}
/>
</View>
);

const pressable = getOuterTextInputPressable(root);
expect(pressable).toHaveStyle({ flexShrink: 1 });
});
30 changes: 30 additions & 0 deletions src/components/__tests__/__snapshots__/TextInput.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ exports[`renders filled TextInput with TextInput.Icon accessories 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
role="none"
style={
{
"flexShrink": 1,
}
}
>
<View
style={
Expand Down Expand Up @@ -506,6 +511,11 @@ exports[`renders filled TextInput with TextInput.Icon accessories when error is
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
role="none"
style={
{
"flexShrink": 1,
}
}
>
<View
style={
Expand Down Expand Up @@ -980,6 +990,11 @@ exports[`renders filled TextInput with label and value 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
role="none"
style={
{
"flexShrink": 1,
}
}
>
<View
style={
Expand Down Expand Up @@ -1178,6 +1193,11 @@ exports[`renders outlined TextInput with TextInput.Icon accessories 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
role="none"
style={
{
"flexShrink": 1,
}
}
>
<View
style={
Expand Down Expand Up @@ -1632,6 +1652,11 @@ exports[`renders outlined TextInput with TextInput.Icon accessories when error i
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
role="none"
style={
{
"flexShrink": 1,
}
}
>
<View
style={
Expand Down Expand Up @@ -2086,6 +2111,11 @@ exports[`renders outlined TextInput with label and value 1`] = `
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
role="none"
style={
{
"flexShrink": 1,
}
}
>
<View
style={
Expand Down
Loading