diff --git a/src/components/TextInput/BaseTextInput/implementation/index.native.tsx b/src/components/TextInput/BaseTextInput/implementation/index.native.tsx index e8ea3cb0b2ff5..42db16aa19008 100644 --- a/src/components/TextInput/BaseTextInput/implementation/index.native.tsx +++ b/src/components/TextInput/BaseTextInput/implementation/index.native.tsx @@ -79,6 +79,7 @@ function BaseTextInput({ iconContainerStyle, shouldUseDefaultLineHeightForPrefix = true, ref, + sentryLabel, ...props }: BaseTextInputProps) { const InputComponent = InputComponentMap.get(type) ?? RNTextInput; @@ -289,10 +290,11 @@ function BaseTextInput({ role={CONST.ROLE.PRESENTATION} onPress={onPress} tabIndex={-1} + accessible={false} + sentryLabel={sentryLabel} // When autoGrowHeight is true we calculate the width for the text input, so it will break lines properly // or if multiline is not supplied we calculate the text input height, using onLayout. onLayout={onLayout} - accessibilityLabel={accessibilityLabel} style={[ autoGrowHeight && !isAutoGrowHeightMarkdown && diff --git a/src/components/TextInput/BaseTextInput/implementation/index.tsx b/src/components/TextInput/BaseTextInput/implementation/index.tsx index 6fc2988bee930..6c9774deac6f7 100644 --- a/src/components/TextInput/BaseTextInput/implementation/index.tsx +++ b/src/components/TextInput/BaseTextInput/implementation/index.tsx @@ -297,11 +297,7 @@ function BaseTextInput({ // eslint-disable-next-line react/jsx-props-no-spreading {...(shouldInterceptSwipe && SwipeInterceptPanResponder.panHandlers)} > - + {!!suffixCharacter && ( @@ -518,7 +526,7 @@ function BaseTextInput({ )} - + {!!inputHelpText && ( {label} diff --git a/src/components/TextInput/TextInputMeasurement/index.tsx b/src/components/TextInput/TextInputMeasurement/index.tsx index 5de306879430c..30eec45eda62a 100644 --- a/src/components/TextInput/TextInputMeasurement/index.tsx +++ b/src/components/TextInput/TextInputMeasurement/index.tsx @@ -35,6 +35,10 @@ function TextInputMeasurement({ onSetTextInputWidth(e.nativeEvent.layout.width); onSetTextInputHeight(e.nativeEvent.layout.height); }} + accessible={false} + accessibilityElementsHidden + importantForAccessibility="no" + aria-hidden > {/* \u200B added to solve the issue of not expanding the text input enough when the value ends with '\n' (https://github.com/Expensify/App/issues/21271) */} {value ? `${value}${value.endsWith('\n') ? '\u200B' : ''}` : placeholder} @@ -66,6 +74,10 @@ function TextInputMeasurement({ styles.hiddenElementOutsideOfWindow, styles.visibilityHidden, ]} + accessible={false} + accessibilityElementsHidden + importantForAccessibility="no" + aria-hidden onLayout={(e) => { if (e.nativeEvent.layout.width === 0 && e.nativeEvent.layout.height === 0) { return; diff --git a/src/pages/signin/SignInPageLayout/Footer.tsx b/src/pages/signin/SignInPageLayout/Footer.tsx index 87bf16af1ebb8..4213f3a8f21b5 100644 --- a/src/pages/signin/SignInPageLayout/Footer.tsx +++ b/src/pages/signin/SignInPageLayout/Footer.tsx @@ -5,8 +5,6 @@ import SignInGradient from '@assets/images/home-fade-gradient--mobile.svg'; import Hoverable from '@components/Hoverable'; import ImageSVG from '@components/ImageSVG'; import Text from '@components/Text'; -import type {LinkProps, PressProps} from '@components/TextLink'; -import TextLink from '@components/TextLink'; import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; @@ -18,14 +16,11 @@ import Socials from '@pages/signin/Socials'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; -import type {SignInPageLayoutProps} from './types'; +import FooterRow from './FooterRow'; +import type {FooterColumnRow, SignInPageLayoutProps} from './types'; type FooterProps = Pick; -type FooterColumnRow = (LinkProps | PressProps) & { - translationPath: TranslationPaths; -}; - type FooterColumnData = { translationPath: TranslationPaths; rows: FooterColumnRow[]; @@ -178,27 +173,25 @@ function Footer({navigateFocus}: FooterProps) { > {translate(column.translationPath)} - {column.rows.map(({href, onPress, translationPath}) => ( - - {(hovered) => ( - - {onPress ? ( - - {translate(translationPath)} - - ) : ( - - {translate(translationPath)} - - )} - - )} + {column.rows.map((row) => ( + + {(hovered) => + row.onPress ? ( + + ) : ( + + ) + } ))} {i === 2 && ( diff --git a/src/pages/signin/SignInPageLayout/FooterRow/index.native.tsx b/src/pages/signin/SignInPageLayout/FooterRow/index.native.tsx new file mode 100644 index 0000000000000..a723a68fbe9c7 --- /dev/null +++ b/src/pages/signin/SignInPageLayout/FooterRow/index.native.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import type {GestureResponderEvent, StyleProp, TextStyle} from 'react-native'; +import {PressableWithoutFeedback} from '@components/Pressable'; +import Text from '@components/Text'; +import useEnvironment from '@hooks/useEnvironment'; +import useThemeStyles from '@hooks/useThemeStyles'; +import type {FooterColumnRow} from '@pages/signin/SignInPageLayout/types'; +import {openLink as openLinkUtil} from '@userActions/Link'; +import CONST from '@src/CONST'; + +type FooterRowProps = FooterColumnRow & { + text: string; + style: StyleProp; +}; + +function FooterRow({href, onPress, translationPath, text, style}: FooterRowProps) { + const styles = useThemeStyles(); + const {environmentURL} = useEnvironment(); + + return ( + { + if (onPress) { + onPress({} as GestureResponderEvent); + return; + } + if (href) { + openLinkUtil(href, environmentURL); + } + }} + > + + {text} + + + ); +} + +export default FooterRow; diff --git a/src/pages/signin/SignInPageLayout/FooterRow/index.tsx b/src/pages/signin/SignInPageLayout/FooterRow/index.tsx new file mode 100644 index 0000000000000..4b2f167b212f5 --- /dev/null +++ b/src/pages/signin/SignInPageLayout/FooterRow/index.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import type {StyleProp, TextStyle} from 'react-native'; +import TextLink from '@components/TextLink'; +import type {FooterColumnRow} from '@pages/signin/SignInPageLayout/types'; + +type FooterRowProps = FooterColumnRow & { + text: string; + style: StyleProp; +}; + +function FooterRow({href, onPress, text, style}: FooterRowProps) { + if (onPress) { + return ( + + {text} + + ); + } + + return ( + + {text} + + ); +} + +export default FooterRow; diff --git a/src/pages/signin/SignInPageLayout/types.ts b/src/pages/signin/SignInPageLayout/types.ts index 9c31cb9b486ad..2546335f483d6 100644 --- a/src/pages/signin/SignInPageLayout/types.ts +++ b/src/pages/signin/SignInPageLayout/types.ts @@ -1,5 +1,7 @@ import type React from 'react'; import type {ForwardedRef} from 'react'; +import type {LinkProps, PressProps} from '@components/TextLink'; +import type {TranslationPaths} from '@src/languages/types'; type SignInPageLayoutProps = { /** The children to show inside the layout */ @@ -35,4 +37,8 @@ type SignInPageLayoutRef = { scrollPageToTop: (animated?: boolean) => void; }; -export type {SignInPageLayoutRef, SignInPageLayoutProps}; +type FooterColumnRow = (LinkProps | PressProps) & { + translationPath: TranslationPaths; +}; + +export type {SignInPageLayoutRef, SignInPageLayoutProps, FooterColumnRow}; diff --git a/tests/ui/AddressPageTest.tsx b/tests/ui/AddressPageTest.tsx index b10f1ebd181fa..f1b3263d71551 100644 --- a/tests/ui/AddressPageTest.tsx +++ b/tests/ui/AddressPageTest.tsx @@ -74,12 +74,13 @@ describe('AddressPageTest', () => { renderPage(SCREENS.SETTINGS.PROFILE.ADDRESS); await waitForBatchedUpdatesWithAct(); - const state = screen.getAllByLabelText('State / Province'); - expect(state.at(1)?.props.value).toEqual('Test'); + const stateInput = screen.getByLabelText('State / Province'); + expect(stateInput.props.value).toEqual('Test'); Navigation.setParams({ country: 'VN', }); await waitForBatchedUpdatesWithAct(); - expect(state?.at(1)?.props.value).toEqual('Test'); + const stateInputAfterParams = screen.getByLabelText('State / Province'); + expect(stateInputAfterParams.props.value).toEqual('Test'); }); }); diff --git a/tests/ui/components/TextInputLabel.tsx b/tests/ui/components/TextInputLabel.tsx index 93d542e2b824b..05fae399cd433 100644 --- a/tests/ui/components/TextInputLabel.tsx +++ b/tests/ui/components/TextInputLabel.tsx @@ -26,7 +26,7 @@ describe('TextInputLabel', () => { labelScale, }); // Find the Animated.Text component by its text content - const labelElement = screen.getByText(longLabel); + const labelElement = screen.getByText(longLabel, {includeHiddenElements: true}); // Verify the component renders the correct text expect(labelElement).toBeTruthy(); // Verify the props for shortening behavior @@ -44,7 +44,7 @@ describe('TextInputLabel', () => { labelScale, }); // Find the Animated.Text component by its text content - const labelElement = screen.getByText(label); + const labelElement = screen.getByText(label, {includeHiddenElements: true}); // Verify the component renders the correct text expect(labelElement).toBeTruthy(); // Verify that numberOfLines and ellipsizeMode are undefined