Skip to content

Commit

Permalink
feat(text-input): add onPress to affix adornment (#4113)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeferson-sb committed Jan 9, 2024
1 parent 441cc65 commit e306072
Show file tree
Hide file tree
Showing 3 changed files with 313 additions and 1 deletion.
28 changes: 27 additions & 1 deletion src/components/TextInput/Adornment/TextInputAffix.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import {
Animated,
GestureResponderEvent,
LayoutChangeEvent,
Pressable,
StyleProp,
StyleSheet,
Text,
Expand All @@ -21,6 +23,14 @@ export type Props = {
*/
text: string;
onLayout?: (event: LayoutChangeEvent) => void;
/**
* Function to execute on press.
*/
onPress?: (e: GestureResponderEvent) => void;
/**
* Accessibility label for the affix. This is read by the screen reader when the user taps the affix.
*/
accessibilityLabel?: string;
/**
* Style that is passed to the Text element.
*/
Expand Down Expand Up @@ -115,6 +125,8 @@ const TextInputAffix = ({
textStyle: labelStyle,
theme: themeOverrides,
onLayout: onTextLayout,
onPress,
accessibilityLabel = text,
}: Props) => {
const theme = useInternalTheme(themeOverrides);
const { AFFIX_OFFSET } = getConstants(theme.isV3);
Expand All @@ -141,7 +153,7 @@ const TextInputAffix = ({

const textColor = getTextColor({ theme, disabled });

return (
const affix = (
<Animated.View
style={[
styles.container,
Expand All @@ -167,7 +179,21 @@ const TextInputAffix = ({
</Text>
</Animated.View>
);

if (onPress) {
return (
<Pressable
onPress={onPress}
accessibilityRole="button"
accessibilityLabel={accessibilityLabel}
>
{affix}
</Pressable>
);
}
return affix;
};

TextInputAffix.displayName = 'TextInput.Affix';

const styles = StyleSheet.create({
Expand Down
19 changes: 19 additions & 0 deletions src/components/__tests__/TextInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,25 @@ it('always applies line height, even if not specified', () => {
});
});

it('call onPress when affix adornment pressed', () => {
const affixOnPress = jest.fn();
const affixTextValue = '+39';
const { getByText, toJSON } = render(
<TextInput
label="Flat input"
placeholder="Enter your phone number"
value={''}
left={<TextInput.Affix text="+39" onPress={affixOnPress} />}
/>
);

fireEvent.press(getByText(affixTextValue));

expect(getByText(affixTextValue)).toBeTruthy();
expect(toJSON()).toMatchSnapshot();
expect(affixOnPress).toHaveBeenCalledTimes(1);
});

describe('maxFontSizeMultiplier', () => {
const createInput = (
type: Exclude<Props['mode'], undefined>,
Expand Down
267 changes: 267 additions & 0 deletions src/components/__tests__/__snapshots__/TextInput.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,272 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`call onPress when affix adornment pressed 1`] = `
<View
style={
[
{
"backgroundColor": "rgba(231, 224, 236, 1)",
"borderTopLeftRadius": 4,
"borderTopRightRadius": 4,
},
{},
]
}
>
<View
collapsable={false}
style={
{
"backgroundColor": "rgba(28, 27, 31, 1)",
"bottom": 0,
"height": 1,
"left": 0,
"position": "absolute",
"right": 0,
"transform": [
{
"scaleY": 0.5,
},
],
"zIndex": 1,
}
}
testID="text-input-underline"
/>
<View
style={
[
{
"paddingBottom": 0,
"paddingTop": 0,
},
{
"minHeight": 56,
},
]
}
>
<View
collapsable={false}
pointerEvents="none"
style={
{
"bottom": 0,
"left": 0,
"opacity": 1,
"position": "absolute",
"right": 0,
"top": 0,
"transform": [
{
"translateX": 0,
},
],
"width": 750,
"zIndex": 3,
}
}
>
<Text
collapsable={false}
maxFontSizeMultiplier={1.5}
numberOfLines={1}
onLayout={[Function]}
onTextLayout={[Function]}
style={
{
"color": "rgba(103, 80, 164, 1)",
"fontFamily": "System",
"fontSize": 16,
"fontWeight": undefined,
"left": 0,
"letterSpacing": 0.15,
"lineHeight": 19.2,
"opacity": 0,
"paddingLeft": 16,
"paddingRight": 16,
"position": "absolute",
"textAlign": "left",
"top": 30,
"transform": [
{
"translateX": 0,
},
{
"translateY": 0,
},
{
"scale": 1,
},
],
"writingDirection": "ltr",
}
}
testID="text-input-flat-label-active"
>
Flat input
</Text>
<Text
collapsable={false}
maxFontSizeMultiplier={1.5}
numberOfLines={1}
style={
{
"color": "rgba(73, 69, 79, 1)",
"fontFamily": "System",
"fontSize": 16,
"fontWeight": undefined,
"left": 0,
"letterSpacing": 0.15,
"lineHeight": 19.2,
"opacity": 0,
"paddingLeft": 16,
"paddingRight": 16,
"position": "absolute",
"textAlign": "left",
"top": 30,
"transform": [
{
"translateX": 0,
},
{
"translateY": 0,
},
{
"scale": 1,
},
],
"writingDirection": "ltr",
}
}
testID="text-input-flat-label-inactive"
>
Flat input
</Text>
</View>
<TextInput
cursorColor="rgba(103, 80, 164, 1)"
editable={true}
maxFontSizeMultiplier={1.5}
multiline={false}
onBlur={[Function]}
onChangeText={[Function]}
onFocus={[Function]}
placeholder=" "
placeholderTextColor="rgba(73, 69, 79, 1)"
selectionColor="rgba(103, 80, 164, 0.54)"
style={
[
{
"margin": 0,
},
{
"height": 56,
},
{
"paddingBottom": 4,
"paddingTop": 24,
},
{
"color": "rgba(73, 69, 79, 1)",
"fontFamily": "System",
"fontSize": 16,
"fontWeight": undefined,
"letterSpacing": 0.15,
"lineHeight": 19.2,
"minWidth": 65,
"paddingLeft": 16,
"paddingRight": 16,
"textAlign": "left",
"textAlignVertical": "center",
},
false,
{
"marginLeft": 0,
"paddingLeft": 40,
},
undefined,
]
}
testID="text-input-flat"
underlineColorAndroid="transparent"
value=""
/>
</View>
<View
accessibilityLabel="+39"
accessibilityRole="button"
accessibilityState={
{
"busy": undefined,
"checked": undefined,
"disabled": undefined,
"expanded": undefined,
"selected": undefined,
}
}
accessibilityValue={
{
"max": undefined,
"min": undefined,
"now": undefined,
"text": undefined,
}
}
accessible={true}
collapsable={false}
focusable={true}
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
>
<View
collapsable={false}
onLayout={[Function]}
style={
{
"alignItems": "center",
"justifyContent": "center",
"left": 16,
"opacity": 0,
"position": "absolute",
"top": null,
}
}
testID="left-affix-adornment"
>
<Text
maxFontSizeMultiplier={1.5}
style={
[
{
"color": "rgba(73, 69, 79, 1)",
},
{
"fontFamily": "System",
"fontSize": 16,
"fontWeight": undefined,
"letterSpacing": 0.15,
"lineHeight": 19.2,
},
undefined,
]
}
testID="left-affix-adornment-text"
>
+39
</Text>
</View>
</View>
</View>
`;

exports[`correctly applies a component as the text label 1`] = `
<View
style={
Expand Down

0 comments on commit e306072

Please sign in to comment.