Skip to content

Commit c20b236

Browse files
committed
fix input icon alignment.
Signed-off-by: krishna2323 <belivethatkg@gmail.com>
1 parent 677bdda commit c20b236

3 files changed

Lines changed: 45 additions & 12 deletions

File tree

src/components/TextInput/BaseTextInput/implementation/index.native.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ function BaseTextInput(
276276
shouldAddPaddingBottom && styles.pb1,
277277
]);
278278

279+
const inputVerticalPadding = StyleUtils.getPaddingVerticalFromStyle(newTextInputContainerStyles);
279280
const inputPaddingLeft = !!prefixCharacter && StyleUtils.getPaddingLeft(prefixCharacterPadding + styles.pl1.paddingLeft);
280281
const inputPaddingRight = !!suffixCharacter && StyleUtils.getPaddingRight(StyleUtils.getCharacterPadding(suffixCharacter) + styles.pr1.paddingRight);
281282

@@ -433,7 +434,7 @@ function BaseTextInput(
433434
)}
434435
{((isFocused && !isReadOnly && shouldShowClearButton) || !shouldHideClearButton) && !!value && (
435436
<TextInputClearButton
436-
style={StyleUtils.getTextInputIconContainerStyles(hasLabel, false)}
437+
style={StyleUtils.getTextInputIconContainerStyles(hasLabel, false, inputVerticalPadding)}
437438
onPressButton={() => {
438439
setValue('');
439440
onClearInput?.();
@@ -445,7 +446,7 @@ function BaseTextInput(
445446
size="small"
446447
color={theme.iconSuccessFill}
447448
style={[
448-
StyleUtils.getTextInputIconContainerStyles(hasLabel, false),
449+
StyleUtils.getTextInputIconContainerStyles(hasLabel, false, inputVerticalPadding),
449450
styles.ml1,
450451
styles.justifyContentStart,
451452
loadingSpinnerStyle,
@@ -455,7 +456,7 @@ function BaseTextInput(
455456
)}
456457
{!!inputProps.secureTextEntry && (
457458
<Checkbox
458-
style={StyleUtils.getTextInputIconContainerStyles(hasLabel)}
459+
style={StyleUtils.getTextInputIconContainerStyles(hasLabel, true, inputVerticalPadding)}
459460
onPress={togglePasswordVisibility}
460461
onMouseDown={(event) => {
461462
event.preventDefault();
@@ -469,7 +470,13 @@ function BaseTextInput(
469470
</Checkbox>
470471
)}
471472
{!inputProps.secureTextEntry && !!icon && (
472-
<View style={[StyleUtils.getTextInputIconContainerStyles(hasLabel), !isReadOnly ? styles.cursorPointer : styles.pointerEventsNone, iconContainerStyle]}>
473+
<View
474+
style={[
475+
StyleUtils.getTextInputIconContainerStyles(hasLabel, true, inputVerticalPadding),
476+
!isReadOnly ? styles.cursorPointer : styles.pointerEventsNone,
477+
iconContainerStyle,
478+
]}
479+
>
473480
<Icon
474481
src={icon}
475482
fill={theme.icon}

src/components/TextInput/BaseTextInput/implementation/index.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,12 @@ function BaseTextInput(
281281
shouldAddPaddingBottom && styles.pb1,
282282
]);
283283

284+
const inputVerticalPadding = StyleUtils.getPaddingVerticalFromStyle(newTextInputContainerStyles);
284285
const inputPaddingLeft = !!prefixCharacter && StyleUtils.getPaddingLeft(prefixCharacterPadding + styles.pl1.paddingLeft);
285286
const inputPaddingRight = !!suffixCharacter && StyleUtils.getPaddingRight(StyleUtils.getCharacterPadding(suffixCharacter) + styles.pr1.paddingRight);
286287
// This is workaround for https://github.com/Expensify/App/issues/47939: in case when user is using Chrome on Android we set inputMode to 'search' to disable autocomplete bar above the keyboard.
287288
// If we need some other inputMode (eg. 'decimal'), then the autocomplete bar will show, but we can do nothing about it as it's a known Chrome bug.
288289
const inputMode = inputProps.inputMode ?? (isMobileChrome() ? 'search' : undefined);
289-
290290
return (
291291
<>
292292
<View
@@ -454,7 +454,7 @@ function BaseTextInput(
454454
}}
455455
>
456456
<TextInputClearButton
457-
style={StyleUtils.getTextInputIconContainerStyles(hasLabel, false)}
457+
style={StyleUtils.getTextInputIconContainerStyles(hasLabel, false, inputVerticalPadding)}
458458
onPressButton={() => {
459459
setValue('');
460460
onClearInput?.();
@@ -467,7 +467,7 @@ function BaseTextInput(
467467
size="small"
468468
color={theme.iconSuccessFill}
469469
style={[
470-
StyleUtils.getTextInputIconContainerStyles(hasLabel, false),
470+
StyleUtils.getTextInputIconContainerStyles(hasLabel, false, inputVerticalPadding),
471471
styles.ml1,
472472
styles.justifyContentStart,
473473
loadingSpinnerStyle,
@@ -477,7 +477,7 @@ function BaseTextInput(
477477
)}
478478
{!!inputProps.secureTextEntry && (
479479
<Checkbox
480-
style={StyleUtils.getTextInputIconContainerStyles(hasLabel)}
480+
style={StyleUtils.getTextInputIconContainerStyles(hasLabel, true, inputVerticalPadding)}
481481
onPress={togglePasswordVisibility}
482482
onMouseDown={(e) => {
483483
e.preventDefault();
@@ -491,7 +491,13 @@ function BaseTextInput(
491491
</Checkbox>
492492
)}
493493
{!inputProps.secureTextEntry && !!icon && (
494-
<View style={[StyleUtils.getTextInputIconContainerStyles(hasLabel), !isReadOnly ? styles.cursorPointer : styles.pointerEventsNone, iconContainerStyle]}>
494+
<View
495+
style={[
496+
StyleUtils.getTextInputIconContainerStyles(hasLabel, true, inputVerticalPadding),
497+
!isReadOnly ? styles.cursorPointer : styles.pointerEventsNone,
498+
iconContainerStyle,
499+
]}
500+
>
495501
<Icon
496502
src={icon}
497503
fill={theme.icon}

src/styles/utils/index.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {StyleSheet} from 'react-native';
2-
import type {AnimatableNumericValue, ColorValue, ImageStyle, PressableStateCallbackType, StyleProp, TextStyle, ViewStyle} from 'react-native';
2+
// eslint-disable-next-line no-restricted-imports
3+
import type {AnimatableNumericValue, Animated, ColorValue, ImageStyle, PressableStateCallbackType, StyleProp, TextStyle, ViewStyle} from 'react-native';
34
import type {OnyxEntry} from 'react-native-onyx';
45
import type {EdgeInsets} from 'react-native-safe-area-context';
56
import type {ValueOf} from 'type-fest';
@@ -727,6 +728,22 @@ function getPaddingBottom(paddingBottom: number): ViewStyle {
727728
};
728729
}
729730

731+
/**
732+
* Get variable padding-bottom as style
733+
*/
734+
function getPaddingVerticalFromStyle(textInputContainerStyles: ViewStyle): number {
735+
const flatStyle = StyleSheet.flatten(textInputContainerStyles);
736+
737+
// Safely extract padding values only if they are numbers
738+
const getNumericPadding = (paddingValue: string | number | Animated.AnimatedNode | null | undefined): number => {
739+
return typeof paddingValue === 'number' ? paddingValue : 0;
740+
};
741+
742+
const paddingTop = getNumericPadding(flatStyle?.paddingTop ?? flatStyle.padding);
743+
const paddingBottom = getNumericPadding(flatStyle?.paddingBottom ?? flatStyle.padding);
744+
return paddingTop + paddingBottom;
745+
}
746+
730747
/**
731748
* Checks to see if the iOS device has safe areas or not
732749
*/
@@ -1237,6 +1254,7 @@ const staticStyleUtils = {
12371254
getPaddingLeft,
12381255
getPaddingRight,
12391256
getPaddingBottom,
1257+
getPaddingVerticalFromStyle,
12401258
hasSafeAreas,
12411259
getHeight,
12421260
getMinimumHeight,
@@ -1381,11 +1399,13 @@ const createStyleUtils = (theme: ThemeColors, styles: ThemeStyles) => ({
13811399
* Computes styles for the text input icon container.
13821400
* Applies horizontal padding if requested, and sets the top margin based on the presence of a label.
13831401
*/
1384-
getTextInputIconContainerStyles: (hasLabel: boolean, includePadding = true) => {
1402+
getTextInputIconContainerStyles: (hasLabel: boolean, includePadding = true, inputPaddingTop = styles.textInputContainer?.padding): ViewStyle => {
13851403
const paddingStyle = includePadding ? {paddingHorizontal: 11} : {};
13861404
return {
13871405
...paddingStyle,
1388-
marginTop: hasLabel ? variables.inputIconMarginTopSmall : variables.inputIconMarginTopLarge,
1406+
marginTop: -(inputPaddingTop / 2),
1407+
height: '100%',
1408+
justifyContent: 'center',
13891409
};
13901410
},
13911411

0 commit comments

Comments
 (0)