From b40a3dab5b96c7847eb545c1ac53fdc3e46e456e Mon Sep 17 00:00:00 2001 From: William Swanson Date: Fri, 26 Sep 2025 17:28:32 -0700 Subject: [PATCH 1/3] Fix SimpleTextInput warnings --- eslint.config.mjs | 1 - .../WalletListModal.test.tsx.snap | 1 + ...reateWalletSelectCryptoScene.test.tsx.snap | 1 + .../DefaultFiatSettingScene.test.tsx.snap | 1 + src/components/themed/SimpleTextInput.tsx | 24 ++++++++++--------- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index a83ac6fc1d2..55d0e99304d 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -364,7 +364,6 @@ export default [ 'src/components/themed/SendFromFioRows.tsx', 'src/components/themed/ShareButtons.tsx', 'src/components/themed/SideMenu.tsx', - 'src/components/themed/Slider.tsx', 'src/components/themed/SwipeableRow.tsx', diff --git a/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap b/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap index fb58e088274..c63bb685b21 100644 --- a/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap +++ b/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap @@ -584,6 +584,7 @@ exports[`WalletListModal should render with loading props 1`] = ` }, ] } + submitBehavior="submit" testID="undefined.textInput" textAlignVertical="top" /> diff --git a/src/__tests__/scenes/__snapshots__/CreateWalletSelectCryptoScene.test.tsx.snap b/src/__tests__/scenes/__snapshots__/CreateWalletSelectCryptoScene.test.tsx.snap index 0b4ae4b45b7..c46d7cb8c39 100644 --- a/src/__tests__/scenes/__snapshots__/CreateWalletSelectCryptoScene.test.tsx.snap +++ b/src/__tests__/scenes/__snapshots__/CreateWalletSelectCryptoScene.test.tsx.snap @@ -691,6 +691,7 @@ exports[`CreateWalletSelectCrypto should render with loading props 1`] = ` }, ] } + submitBehavior="submit" testID="undefined.textInput" textAlignVertical="top" /> diff --git a/src/__tests__/scenes/__snapshots__/DefaultFiatSettingScene.test.tsx.snap b/src/__tests__/scenes/__snapshots__/DefaultFiatSettingScene.test.tsx.snap index 09adc005a88..0df6b1c46eb 100644 --- a/src/__tests__/scenes/__snapshots__/DefaultFiatSettingScene.test.tsx.snap +++ b/src/__tests__/scenes/__snapshots__/DefaultFiatSettingScene.test.tsx.snap @@ -691,6 +691,7 @@ exports[`DefaultFiatSettingComponent should render with loading props 1`] = ` }, ] } + submitBehavior="submit" testID="undefined.textInput" textAlignVertical="top" /> diff --git a/src/components/themed/SimpleTextInput.tsx b/src/components/themed/SimpleTextInput.tsx index 6aefaaaddfa..465e58967ff 100644 --- a/src/components/themed/SimpleTextInput.tsx +++ b/src/components/themed/SimpleTextInput.tsx @@ -53,6 +53,7 @@ export interface SimpleTextInputProps extends LayoutStyleProps { onClear?: () => void onFocus?: () => void onCancel?: () => void + onSubmitEditing?: () => void // Other React Native TextInput properties: autoCapitalize?: 'none' | 'sentences' | 'words' | 'characters' // Defaults to 'sentences' @@ -66,7 +67,6 @@ export interface SimpleTextInputProps extends LayoutStyleProps { | 'email-address' | 'phone-pad' // Defaults to 'default' maxLength?: number - onSubmitEditing?: () => void returnKeyType?: SimpleTextInputReturnKeyType // Defaults to 'done' secureTextEntry?: boolean // Defaults to 'false' testID?: string @@ -128,7 +128,7 @@ export const SimpleTextInput = React.forwardRef< autoCorrect, autoFocus = false, blurOnClear = false, - blurOnSubmit, + blurOnSubmit = false, disabled = false, keyboardType, maxLength, @@ -136,7 +136,7 @@ export const SimpleTextInput = React.forwardRef< secureTextEntry, active, testID, - ...marginRemProps + ...layoutProps } = props const theme = useTheme() const themeRem = theme.rem(1) @@ -285,7 +285,7 @@ export const SimpleTextInput = React.forwardRef< }, [active, focusAnimation, baseDuration, animationDelay]) return ( - + @@ -357,7 +357,7 @@ export const SimpleTextInput = React.forwardRef< - {isIos && (isFocused || active === true) && ( + {isIos && (isFocused || active === true) ? ( - )} + ) : null} ) }) @@ -510,14 +510,16 @@ const CancelText = styled(UnscaledText)(theme => { } }) +type ColorInterpolateFn = ( + focusValue: SharedValue, + disabledValue: SharedValue +) => string + function useAnimatedColorInterpolateFn( fromColor: string, toColor: string, disabledColor: string -): ( - focusValue: SharedValue, - disabledValue: SharedValue -) => string { +): ColorInterpolateFn { const interpolateFn = useMemo(() => { return ( focusValue: SharedValue, From b47e94c1d0491fc2e48205a8a03af18e1a1cb48f Mon Sep 17 00:00:00 2001 From: William Swanson Date: Sat, 27 Sep 2025 00:16:05 -0700 Subject: [PATCH 2/3] Use raw views in SimpleTextInput The `styled` HOC is really hard to reason about, which is blocking the layout changes we need to make. --- .../WalletListModal.test.tsx.snap | 23 +- ...reateWalletSelectCryptoScene.test.tsx.snap | 24 +- .../DefaultFiatSettingScene.test.tsx.snap | 24 +- src/components/themed/SimpleTextInput.tsx | 343 ++++++++---------- 4 files changed, 175 insertions(+), 239 deletions(-) diff --git a/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap b/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap index c63bb685b21..6fdde553efa 100644 --- a/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap +++ b/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap @@ -226,24 +226,19 @@ exports[`WalletListModal should render with loading props 1`] = ` @@ -259,8 +254,6 @@ exports[`WalletListModal should render with loading props 1`] = ` } accessible={false} collapsable={false} - disableAnimation={0} - focusAnimation={0} focusable={true} jestAnimatedProps={ { @@ -302,7 +295,6 @@ exports[`WalletListModal should render with loading props 1`] = ` onResponderTerminate={[Function]} onResponderTerminationRequest={[Function]} onStartShouldSetResponder={[Function]} - scale={1} style={ [ { @@ -352,7 +344,6 @@ exports[`WalletListModal should render with loading props 1`] = ` ] } nativeID="3" - size={22} style={ [ { @@ -462,7 +453,6 @@ exports[`WalletListModal should render with loading props 1`] = ` ] } nativeID="5" - size={0} style={ [ { @@ -531,8 +521,6 @@ exports[`WalletListModal should render with loading props 1`] = ` autoFocus={false} collapsable={false} defaultValue="" - disableAnimation={0} - focusAnimation={0} forwardedRef={[Function]} jestAnimatedProps={ { @@ -651,7 +639,6 @@ exports[`WalletListModal should render with loading props 1`] = ` ] } nativeID="8" - size={0} style={ [ { diff --git a/src/__tests__/scenes/__snapshots__/CreateWalletSelectCryptoScene.test.tsx.snap b/src/__tests__/scenes/__snapshots__/CreateWalletSelectCryptoScene.test.tsx.snap index c46d7cb8c39..60ba7d5ab98 100644 --- a/src/__tests__/scenes/__snapshots__/CreateWalletSelectCryptoScene.test.tsx.snap +++ b/src/__tests__/scenes/__snapshots__/CreateWalletSelectCryptoScene.test.tsx.snap @@ -331,25 +331,19 @@ exports[`CreateWalletSelectCrypto should render with loading props 1`] = ` @@ -365,8 +359,6 @@ exports[`CreateWalletSelectCrypto should render with loading props 1`] = ` } accessible={false} collapsable={false} - disableAnimation={0} - focusAnimation={0} focusable={true} jestAnimatedProps={ { @@ -408,7 +400,6 @@ exports[`CreateWalletSelectCrypto should render with loading props 1`] = ` onResponderTerminate={[Function]} onResponderTerminationRequest={[Function]} onStartShouldSetResponder={[Function]} - scale={1} style={ [ { @@ -458,7 +449,6 @@ exports[`CreateWalletSelectCrypto should render with loading props 1`] = ` ] } nativeID="2" - size={22} style={ [ { @@ -568,7 +558,6 @@ exports[`CreateWalletSelectCrypto should render with loading props 1`] = ` ] } nativeID="4" - size={0} style={ [ { @@ -639,8 +628,6 @@ exports[`CreateWalletSelectCrypto should render with loading props 1`] = ` autoFocus={false} collapsable={false} defaultValue="" - disableAnimation={0} - focusAnimation={0} forwardedRef={[Function]} jestAnimatedProps={ { @@ -758,7 +745,6 @@ exports[`CreateWalletSelectCrypto should render with loading props 1`] = ` ] } nativeID="7" - size={0} style={ [ { diff --git a/src/__tests__/scenes/__snapshots__/DefaultFiatSettingScene.test.tsx.snap b/src/__tests__/scenes/__snapshots__/DefaultFiatSettingScene.test.tsx.snap index 0df6b1c46eb..1f538d88864 100644 --- a/src/__tests__/scenes/__snapshots__/DefaultFiatSettingScene.test.tsx.snap +++ b/src/__tests__/scenes/__snapshots__/DefaultFiatSettingScene.test.tsx.snap @@ -330,25 +330,19 @@ exports[`DefaultFiatSettingComponent should render with loading props 1`] = ` @@ -364,8 +358,6 @@ exports[`DefaultFiatSettingComponent should render with loading props 1`] = ` } accessible={false} collapsable={false} - disableAnimation={0} - focusAnimation={0} focusable={true} jestAnimatedProps={ { @@ -407,7 +399,6 @@ exports[`DefaultFiatSettingComponent should render with loading props 1`] = ` onResponderTerminate={[Function]} onResponderTerminationRequest={[Function]} onStartShouldSetResponder={[Function]} - scale={1} style={ [ { @@ -457,7 +448,6 @@ exports[`DefaultFiatSettingComponent should render with loading props 1`] = ` ] } nativeID="2" - size={22} style={ [ { @@ -567,7 +557,6 @@ exports[`DefaultFiatSettingComponent should render with loading props 1`] = ` ] } nativeID="4" - size={0} style={ [ { @@ -638,8 +627,6 @@ exports[`DefaultFiatSettingComponent should render with loading props 1`] = ` autoFocus={false} collapsable={false} defaultValue="" - disableAnimation={0} - focusAnimation={0} forwardedRef={[Function]} jestAnimatedProps={ { @@ -758,7 +745,6 @@ exports[`DefaultFiatSettingComponent should render with loading props 1`] = ` ] } nativeID="7" - size={0} style={ [ { diff --git a/src/components/themed/SimpleTextInput.tsx b/src/components/themed/SimpleTextInput.tsx index 465e58967ff..0d70aead349 100644 --- a/src/components/themed/SimpleTextInput.tsx +++ b/src/components/themed/SimpleTextInput.tsx @@ -20,13 +20,12 @@ import { } from '../../hooks/useLayoutStyle' import { lstrings } from '../../locales/strings' import { EdgeTouchableWithoutFeedback } from '../common/EdgeTouchableWithoutFeedback' -import { styled, styledWithRef } from '../hoc/styled' import { type AnimatedIconComponent, ChevronBackAnimated, CloseIconAnimated } from '../icons/ThemedIcons' -import { useTheme } from '../services/ThemeContext' +import { cacheStyles, type Theme, useTheme } from '../services/ThemeContext' import { UnscaledText } from '../text/UnscaledText' const AnimatedTextInput = Animated.createAnimatedComponent(TextInput) @@ -139,15 +138,19 @@ export const SimpleTextInput = React.forwardRef< ...layoutProps } = props const theme = useTheme() + const styles = getStyles(theme) const themeRem = theme.rem(1) + // TODO: Remove aroundRem=0 prop once this component's design consideration + // has changed to expecting 0.5rem default margins. + const layoutStyle = useLayoutStyle({ aroundRem: 0, ...layoutProps }) + const hasIcon = Icon != null const isIos = Platform.OS === 'ios' - const valueRef = useSharedValue(value) - const [isFocused, setIsFocused] = React.useState(false) + const valueRef = useSharedValue(value) const handleChangeText = (value: string): void => { valueRef.value = value if (onChangeText != null) onChangeText(value) @@ -236,6 +239,58 @@ export const SimpleTextInput = React.forwardRef< if (onSubmitEditing != null) onSubmitEditing() }) + React.useEffect(() => { + if (active == null) return + focusAnimation.value = active + ? withTiming(1, { duration: baseDuration }) + : withDelay(animationDelay, withTiming(0, { duration: baseDuration })) + }, [active, focusAnimation, baseDuration, animationDelay]) + + // -------------------------------------------------------------------- + // Colors + // -------------------------------------------------------------------- + + const placeholderTextColor = useMemo(() => { + return disabled + ? theme.textInputPlaceholderColorDisabled + : isFocused + ? theme.textInputPlaceholderColorFocused + : theme.textInputPlaceholderColor + }, [ + disabled, + isFocused, + theme.textInputPlaceholderColor, + theme.textInputPlaceholderColorDisabled, + theme.textInputPlaceholderColorFocused + ]) + const interpolateInputBackgroundColor = useAnimatedColorInterpolateFn( + theme.textInputBackgroundColor, + theme.textInputBackgroundColorFocused, + theme.textInputBackgroundColorDisabled + ) + const interpolateOutlineColor = useAnimatedColorInterpolateFn( + theme.textInputBorderColor, + theme.textInputBorderColorFocused, + theme.textInputBorderColorDisabled + ) + const interpolateTextColor = useAnimatedColorInterpolateFn( + theme.textInputTextColor, + theme.textInputTextColorFocused, + theme.textInputTextColorDisabled + ) + const interpolateIconColor = useAnimatedColorInterpolateFn( + theme.textInputIconColor, + theme.textInputIconColorFocused, + theme.textInputIconColorDisabled + ) + const iconColor = useDerivedValue(() => + interpolateIconColor(focusAnimation, disableAnimation) + ) + + // -------------------------------------------------------------------- + // Styles + // -------------------------------------------------------------------- + const backIconSize = useDerivedValue(() => isIos ? 0 : interpolate(focusAnimation.value, [0, 1], [0, themeRem]) ) @@ -252,40 +307,42 @@ export const SimpleTextInput = React.forwardRef< return hasValue ? themeRem : focusAnimation.value * themeRem }) - const scale = useDerivedValue(() => scaleProp?.value ?? 1) - - const interpolateIconColor = useAnimatedColorInterpolateFn( - theme.textInputIconColor, - theme.textInputIconColorFocused, - theme.textInputIconColorDisabled - ) - const iconColor = useDerivedValue(() => - interpolateIconColor(focusAnimation, disableAnimation) - ) - - const placeholderTextColor = useMemo(() => { - return disabled - ? theme.textInputPlaceholderColorDisabled - : isFocused - ? theme.textInputPlaceholderColorFocused - : theme.textInputPlaceholderColor - }, [ - disabled, - isFocused, - theme.textInputPlaceholderColor, - theme.textInputPlaceholderColorDisabled, - theme.textInputPlaceholderColorFocused - ]) + const backIconStyle = useAnimatedStyle(() => ({ + width: backIconSize.value, + opacity: backIconSize.value + })) + const leftIconStyle = useAnimatedStyle(() => ({ + width: leftIconSize.value, + opacity: leftIconSize.value + })) + const rightIconStyle = useAnimatedStyle(() => ({ + width: rightIconSize.value, + opacity: rightIconSize.value + })) - React.useEffect(() => { - if (active == null) return - focusAnimation.value = active - ? withTiming(1, { duration: baseDuration }) - : withDelay(animationDelay, withTiming(0, { duration: baseDuration })) - }, [active, focusAnimation, baseDuration, animationDelay]) + const inputContainerStyle = useAnimatedStyle(() => { + 'worklet' + const scale = scaleProp?.value ?? 1 + return { + backgroundColor: interpolateInputBackgroundColor( + focusAnimation, + disableAnimation + ), + borderColor: interpolateOutlineColor(focusAnimation, disableAnimation), + opacity: interpolate(scale, [1, 0.5], [1, 0]), + transform: [ + { + scale: interpolate(scale, [1, 0], [1, 0.75]) + } + ] + } + }) + const textInputStyle = useAnimatedStyle(() => ({ + color: interpolateTextColor(focusAnimation, disableAnimation) + })) return ( - + - - + + {Icon == null ? null : ( )} - + - + - + - - + - + - - + - - - + + + {isIos && (isFocused || active === true) ? ( - - - {lstrings.string_cancel_cap} - - + + {lstrings.string_cancel_cap} + ) : null} - + ) }) -const ContainerView = styled(View)<{ - marginRemProps: LayoutStyleProps -}>(theme => ({ marginRemProps }) => { - // TODO: Remove aroundRem=0 prop once this component's design consideration - // has changed to expecting 0.5rem default margins. - const marginRemStyle = useLayoutStyle({ aroundRem: 0, ...marginRemProps }) - return [ - marginRemStyle, - { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center' - } - ] -}) - -const InputContainerView = styled(Animated.View)<{ - disableAnimation: SharedValue - focusAnimation: SharedValue - scale: SharedValue -}>(theme => ({ disableAnimation, focusAnimation, scale }) => { - const interpolateInputBackgroundColor = useAnimatedColorInterpolateFn( - theme.textInputBackgroundColor, - theme.textInputBackgroundColorFocused, - theme.textInputBackgroundColorDisabled - ) - const interpolateOutlineColor = useAnimatedColorInterpolateFn( - theme.textInputBorderColor, - theme.textInputBorderColorFocused, - theme.textInputBorderColorDisabled - ) - - return [ - { - alignItems: 'center', - borderWidth: theme.textInputBorderWidth, - borderRadius: theme.rem(theme.textInputBorderRadius), - flexDirection: 'row', - flexGrow: 1, - flexShrink: 1, - paddingHorizontal: theme.rem(1), - paddingVertical: theme.rem(0.75) - }, - useAnimatedStyle(() => { - 'worklet' - return { - backgroundColor: interpolateInputBackgroundColor( - focusAnimation, - disableAnimation - ), - borderColor: interpolateOutlineColor(focusAnimation, disableAnimation), - opacity: interpolate(scale.value, [1, 0.5], [1, 0]), - transform: [ - { - scale: interpolate(scale.value, [1, 0], [1, 0.75]) - } - ] - } - }) - ] -}) - -const SideContainer = styled(Animated.View)<{ size: SharedValue }>( - theme => - ({ size }) => { - return [ - { - alignItems: 'stretch', - aspectRatio: 1 - }, - useAnimatedStyle(() => ({ - width: size.value, - opacity: size.value - })) - ] - } -) - -const InnerContainer = styled(View)({ - flex: 1 -}) - -const InputField = styledWithRef(AnimatedTextInput)<{ - disableAnimation: SharedValue - focusAnimation: SharedValue -}>(theme => ({ disableAnimation, focusAnimation }) => { - const interpolateTextColor = useAnimatedColorInterpolateFn( - theme.textInputTextColor, - theme.textInputTextColorFocused, - theme.textInputTextColorDisabled - ) - - return [ - { - flexGrow: 1, - flexShrink: 1, - fontFamily: theme.fontFaceDefault, - paddingHorizontal: theme.rem(0.5), - paddingVertical: 0, - margin: 0, - fontSize: theme.rem(1) - }, - useAnimatedStyle(() => ({ - color: interpolateTextColor(focusAnimation, disableAnimation) - })) - ] -}) +const getStyles = cacheStyles((theme: Theme) => ({ + container: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center' + }, + inputContainer: { + alignItems: 'center', + borderWidth: theme.textInputBorderWidth, + borderRadius: theme.rem(theme.textInputBorderRadius), + flexDirection: 'row', + flexGrow: 1, + flexShrink: 1, + paddingHorizontal: theme.rem(1), + paddingVertical: theme.rem(0.75) + }, + iconContainer: { + alignItems: 'stretch', + aspectRatio: 1 + }, + innerContainer: { + flex: 1 + }, + textInput: { + flexGrow: 1, + flexShrink: 1, + fontFamily: theme.fontFaceDefault, + paddingHorizontal: theme.rem(0.5), + paddingVertical: 0, + margin: 0, + fontSize: theme.rem(1) + }, -const TouchContainer = styled(TouchableOpacity)(theme => ({ // Increase tappable area with padding, while net 0 with negative margin to // visually appear as if 0 margins/padding - padding: theme.rem(1), - margin: -theme.rem(1) -})) + rightIconTouchable: { + padding: theme.rem(1), + margin: -theme.rem(1) + }, -const CancelButton = styled(View)(theme => () => { - return { + cancelButton: { alignItems: 'center', justifyContent: 'center', marginLeft: theme.rem(0.5) - } -}) - -const CancelText = styled(UnscaledText)(theme => { - return { + }, + cancelText: { color: theme.textInputIconColorFocused, fontFamily: theme.fontFaceDefault, fontSize: theme.rem(1), @@ -508,7 +485,7 @@ const CancelText = styled(UnscaledText)(theme => { marginHorizontal: theme.rem(0.5), flexShrink: 0 } -}) +})) type ColorInterpolateFn = ( focusValue: SharedValue, From c7d68534d62cba1c0188e818458d0b7cdebc4876 Mon Sep 17 00:00:00 2001 From: William Swanson Date: Tue, 30 Sep 2025 10:55:11 -0700 Subject: [PATCH 3/3] Fix crash in SimpleTextInput CSS --- .../WalletListModal.test.tsx.snap | 210 +++++++++-------- ...reateWalletSelectCryptoScene.test.tsx.snap | 212 +++++++++-------- .../DefaultFiatSettingScene.test.tsx.snap | 214 +++++++++--------- src/components/themed/SimpleTextInput.tsx | 142 ++++++------ 4 files changed, 400 insertions(+), 378 deletions(-) diff --git a/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap b/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap index 6fdde553efa..42b91ea6a50 100644 --- a/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap +++ b/src/__tests__/modals/__snapshots__/WalletListModal.test.tsx.snap @@ -330,16 +330,20 @@ exports[`WalletListModal should render with loading props 1`] = ` jestAnimatedStyle={ { "value": { - "opacity": 22, - "width": 22, + "marginRight": 0, + "transform": [ + { + "scale": 1, + }, + ], }, } } jestInlineStyle={ [ { - "alignItems": "stretch", - "aspectRatio": 1, + "height": 22, + "width": 22, }, ] } @@ -347,12 +351,16 @@ exports[`WalletListModal should render with loading props 1`] = ` style={ [ { - "alignItems": "stretch", - "aspectRatio": 1, + "height": 22, + "width": 22, }, { - "opacity": 22, - "width": 22, + "marginRight": 0, + "transform": [ + { + "scale": 1, + }, + ], }, ] } @@ -439,16 +447,20 @@ exports[`WalletListModal should render with loading props 1`] = ` jestAnimatedStyle={ { "value": { - "opacity": 0, - "width": 0, + "marginRight": -22, + "transform": [ + { + "scale": 0, + }, + ], }, } } jestInlineStyle={ [ { - "alignItems": "stretch", - "aspectRatio": 1, + "height": 22, + "width": 22, }, ] } @@ -456,12 +468,16 @@ exports[`WalletListModal should render with loading props 1`] = ` style={ [ { - "alignItems": "stretch", - "aspectRatio": 1, + "height": 22, + "width": 22, }, { - "opacity": 0, - "width": 0, + "marginRight": -22, + "transform": [ + { + "scale": 0, + }, + ], }, ] } @@ -479,7 +495,7 @@ exports[`WalletListModal should render with loading props 1`] = ` "value": { "color": "rgba(255, 255, 255, 0.5019607843137255)", "fontFamily": "Material Icons", - "fontSize": 0, + "fontSize": 22, "fontStyle": "normal", "fontWeight": "normal", }, @@ -492,7 +508,7 @@ exports[`WalletListModal should render with loading props 1`] = ` { "color": "rgba(255, 255, 255, 0.5019607843137255)", "fontFamily": "Material Icons", - "fontSize": 0, + "fontSize": 22, "fontStyle": "normal", "fontWeight": "normal", }, @@ -503,80 +519,70 @@ exports[`WalletListModal should render with loading props 1`] = ` - - - + "flex": 1, + "fontFamily": "Quicksand-Regular", + "fontSize": 22, + "margin": 0, + "paddingHorizontal": 11, + "paddingVertical": 0, + }, + ] + } + nativeID="7" + onBlur={[Function]} + onChangeText={[Function]} + onFocus={[Function]} + onSubmitEditing={[Function]} + placeholder="Search Wallets" + placeholderTextColor="rgba(255, 255, 255, .5)" + returnKeyType="search" + selectionColor="rgba(255, 255, 255, .25)" + style={ + [ + { + "flex": 1, + "fontFamily": "Quicksand-Regular", + "fontSize": 22, + "margin": 0, + "paddingHorizontal": 11, + "paddingVertical": 0, + }, + { + "color": "rgba(255, 255, 255, 1)", + }, + ] + } + submitBehavior="submit" + testID="undefined.textInput" + textAlignVertical="top" + /> - - - + "flex": 1, + "fontFamily": "Quicksand-Regular", + "fontSize": 22, + "margin": 0, + "paddingHorizontal": 11, + "paddingVertical": 0, + }, + ] + } + nativeID="6" + onBlur={[Function]} + onChangeText={[Function]} + onFocus={[Function]} + onSubmitEditing={[Function]} + placeholder="Search Wallets" + placeholderTextColor="rgba(255, 255, 255, .5)" + selectionColor="rgba(255, 255, 255, .25)" + style={ + [ + { + "flex": 1, + "fontFamily": "Quicksand-Regular", + "fontSize": 22, + "margin": 0, + "paddingHorizontal": 11, + "paddingVertical": 0, + }, + { + "color": "rgba(255, 255, 255, 1)", + }, + ] + } + submitBehavior="submit" + testID="undefined.textInput" + textAlignVertical="top" + /> - - - + "flex": 1, + "fontFamily": "Quicksand-Regular", + "fontSize": 22, + "margin": 0, + "paddingHorizontal": 11, + "paddingVertical": 0, + }, + ] + } + nativeID="6" + onBlur={[Function]} + onChangeText={[Function]} + onFocus={[Function]} + onSubmitEditing={[Function]} + placeholder="Choose a fiat currency" + placeholderTextColor="rgba(255, 255, 255, .5)" + returnKeyType="search" + selectionColor="rgba(255, 255, 255, .25)" + style={ + [ + { + "flex": 1, + "fontFamily": "Quicksand-Regular", + "fontSize": 22, + "margin": 0, + "paddingHorizontal": 11, + "paddingVertical": 0, + }, + { + "color": "rgba(255, 255, 255, 1)", + }, + ] + } + submitBehavior="submit" + testID="undefined.textInput" + textAlignVertical="top" + /> - isIos ? 0 : interpolate(focusAnimation.value, [0, 1], [0, themeRem]) - ) - const leftIconSize = useDerivedValue(() => { - const hasValue = valueRef.value !== '' - return hasIcon - ? hasValue && (active == null || !active) - ? 0 - : interpolate(focusAnimation.value, [0, 1], [themeRem, 0]) - : 0 + const backIconStyle = useAnimatedStyle(() => { + const scale = isIos ? 0 : focusAnimation.value + return { + transform: [{ scale }], + marginRight: (scale - 1) * themeRem + } }) - const rightIconSize = useDerivedValue(() => { - const hasValue = valueRef.value !== '' - return hasValue ? themeRem : focusAnimation.value * themeRem + + const leftIconStyle = useAnimatedStyle(() => { + const scale = !hasIcon + ? 0 + : valueRef.value !== '' && active !== true + ? 0 + : 1 - focusAnimation.value + return { + transform: [{ scale }], + marginRight: (scale - 1) * themeRem + } }) - const backIconStyle = useAnimatedStyle(() => ({ - width: backIconSize.value, - opacity: backIconSize.value - })) - const leftIconStyle = useAnimatedStyle(() => ({ - width: leftIconSize.value, - opacity: leftIconSize.value - })) - const rightIconStyle = useAnimatedStyle(() => ({ - width: rightIconSize.value, - opacity: rightIconSize.value - })) + const clearIconStyle = useAnimatedStyle(() => { + const scale = valueRef.value !== '' ? 1 : focusAnimation.value + return { + transform: [{ scale }], + marginLeft: (scale - 1) * themeRem + } + }) const inputContainerStyle = useAnimatedStyle(() => { 'worklet' @@ -337,6 +336,7 @@ export const SimpleTextInput = React.forwardRef< ] } }) + const textInputStyle = useAnimatedStyle(() => ({ color: interpolateTextColor(focusAnimation, disableAnimation) })) @@ -351,11 +351,11 @@ export const SimpleTextInput = React.forwardRef< }} > - - {Icon == null ? null : ( - - )} - + {Icon == null ? null : ( + + + + )} - + - - - + - - + + @@ -447,15 +444,11 @@ const getStyles = cacheStyles((theme: Theme) => ({ paddingVertical: theme.rem(0.75) }, iconContainer: { - alignItems: 'stretch', - aspectRatio: 1 - }, - innerContainer: { - flex: 1 + width: theme.rem(1), + height: theme.rem(1) }, textInput: { - flexGrow: 1, - flexShrink: 1, + flex: 1, fontFamily: theme.fontFaceDefault, paddingHorizontal: theme.rem(0.5), paddingVertical: 0, @@ -463,13 +456,6 @@ const getStyles = cacheStyles((theme: Theme) => ({ fontSize: theme.rem(1) }, - // Increase tappable area with padding, while net 0 with negative margin to - // visually appear as if 0 margins/padding - rightIconTouchable: { - padding: theme.rem(1), - margin: -theme.rem(1) - }, - cancelButton: { alignItems: 'center', justifyContent: 'center',