mirror of
https://github.com/inaturalist/iNaturalistReactNative.git
synced 2026-04-20 06:53:56 -04:00
feat: add labels to tab buttons (#2611)
* feat: add text labels to bottom tabs * fix: treat icon and text as single pressable for screen readers in bottom tabs * feat: float AddObs button outside of bottom tab bar Closes MOB-254 --------- Co-authored-by: Kirk van Gorkom <55742+kvangork@users.noreply.github.com>
This commit is contained in:
@@ -76,7 +76,7 @@ const AddObsButton = (): React.Node => {
|
||||
modal={addObsModal}
|
||||
/>
|
||||
<GradientButton
|
||||
sizeClassName="w-[69px] h-[69px]"
|
||||
sizeClassName="w-[69px] h-[69px] mb-[5px]"
|
||||
onPress={isAllAddObsOptionsMode
|
||||
? openModal
|
||||
: navToARCamera}
|
||||
|
||||
@@ -21,6 +21,8 @@ interface Props extends PropsWithChildren {
|
||||
disabled?: boolean;
|
||||
height?: number;
|
||||
icon?: string;
|
||||
// Only show the icon with all the same layout, don't make it a button
|
||||
iconOnly?: boolean;
|
||||
onPress: ( _event?: GestureResponderEvent ) => void;
|
||||
// Inserts a white or colored view under the icon so an holes in the shape show as
|
||||
// white
|
||||
@@ -35,6 +37,15 @@ interface Props extends PropsWithChildren {
|
||||
|
||||
const MIN_ACCESSIBLE_DIM = 44;
|
||||
|
||||
const WRAPPER_STYLE: ViewStyle = {
|
||||
alignItems: "center",
|
||||
justifyContent: "center"
|
||||
};
|
||||
|
||||
const CONTAINED_WRAPPER_STYLE: ViewStyle = {
|
||||
borderRadius: 9999
|
||||
};
|
||||
|
||||
// Similar to IconButton in react-native-paper, except this allows independent
|
||||
// control over touchable area with `width` and `height` *and* the size of
|
||||
// the icon with `size`
|
||||
@@ -46,6 +57,7 @@ const INatIconButton = ( {
|
||||
disabled = false,
|
||||
height = MIN_ACCESSIBLE_DIM,
|
||||
icon,
|
||||
iconOnly,
|
||||
onPress,
|
||||
preventTransparency,
|
||||
size = 18,
|
||||
@@ -67,12 +79,12 @@ const INatIconButton = ( {
|
||||
`Height cannot be less than ${MIN_ACCESSIBLE_DIM}. Use IconButton for smaller buttons.`
|
||||
);
|
||||
}
|
||||
if ( !accessibilityLabel ) {
|
||||
if ( !accessibilityLabel && !iconOnly ) {
|
||||
throw new Error(
|
||||
"Button needs an accessibility label"
|
||||
);
|
||||
}
|
||||
const opacity = ( pressed: boolean ) => {
|
||||
const getOpacity = React.useCallback( ( pressed: boolean ) => {
|
||||
if ( disabled ) {
|
||||
return 0.5;
|
||||
}
|
||||
@@ -80,7 +92,84 @@ const INatIconButton = ( {
|
||||
return 0.95;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
}, [disabled] );
|
||||
|
||||
const wrapperStyle = React.useMemo( ( ) => ( [
|
||||
{ width, height },
|
||||
WRAPPER_STYLE,
|
||||
mode === "contained" && {
|
||||
backgroundColor: preventTransparency
|
||||
? undefined
|
||||
: backgroundColor,
|
||||
...CONTAINED_WRAPPER_STYLE
|
||||
},
|
||||
style
|
||||
] ), [
|
||||
backgroundColor,
|
||||
height,
|
||||
mode,
|
||||
preventTransparency,
|
||||
style,
|
||||
width
|
||||
] );
|
||||
|
||||
const content = (
|
||||
<View
|
||||
className={classnames(
|
||||
"relative",
|
||||
// This degree of pixel pushing was meant for a ~22px icon, so it
|
||||
// might have to be made relative, but it's barely noticeable for
|
||||
// most icons
|
||||
Platform.OS === "android"
|
||||
? "top-[0.8px]"
|
||||
: "left-[0.2px] top-[0.1px]"
|
||||
)}
|
||||
>
|
||||
{ backgroundColor && preventTransparency && (
|
||||
<View
|
||||
// Position and size need to be dynamic
|
||||
// eslint-disable-next-line react-native/no-inline-styles
|
||||
style={{
|
||||
opacity: disabled
|
||||
? 0
|
||||
: 1,
|
||||
position: "absolute",
|
||||
top: preventTransparency
|
||||
? 2
|
||||
: -2,
|
||||
start: preventTransparency
|
||||
? 2
|
||||
: -2,
|
||||
width: preventTransparency
|
||||
? size - 4
|
||||
: size + 4,
|
||||
height: preventTransparency
|
||||
? size - 4
|
||||
: size + 4,
|
||||
backgroundColor,
|
||||
borderRadius: 9999
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{
|
||||
children || (
|
||||
<INatIcon
|
||||
name={icon}
|
||||
size={size}
|
||||
color={String( color || colors?.darkGray )}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</View>
|
||||
);
|
||||
|
||||
if ( iconOnly ) {
|
||||
return (
|
||||
<View style={wrapperStyle} testID={testID}>
|
||||
{ content }
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
@@ -91,70 +180,12 @@ const INatIconButton = ( {
|
||||
disabled={disabled}
|
||||
onPress={onPress}
|
||||
style={( { pressed } ) => [
|
||||
{
|
||||
opacity: opacity( pressed ),
|
||||
width,
|
||||
height,
|
||||
justifyContent: "center",
|
||||
alignItems: "center"
|
||||
},
|
||||
mode === "contained" && {
|
||||
backgroundColor: preventTransparency
|
||||
? undefined
|
||||
: backgroundColor,
|
||||
borderRadius: 9999
|
||||
},
|
||||
style
|
||||
...wrapperStyle,
|
||||
{ opacity: getOpacity( pressed ) }
|
||||
]}
|
||||
testID={testID}
|
||||
>
|
||||
<View
|
||||
className={classnames(
|
||||
"relative",
|
||||
// This degree of pixel pushing was meant for a ~22px icon, so it
|
||||
// might have to be made relative, but it's barely noticeable for
|
||||
// most icons
|
||||
Platform.OS === "android"
|
||||
? "top-[0.8px]"
|
||||
: "left-[0.2px] top-[0.1px]"
|
||||
)}
|
||||
>
|
||||
{ backgroundColor && preventTransparency && (
|
||||
<View
|
||||
// Position and size need to be dynamic
|
||||
// eslint-disable-next-line react-native/no-inline-styles
|
||||
style={{
|
||||
opacity: disabled
|
||||
? 0
|
||||
: 1,
|
||||
position: "absolute",
|
||||
top: preventTransparency
|
||||
? 2
|
||||
: -2,
|
||||
start: preventTransparency
|
||||
? 2
|
||||
: -2,
|
||||
width: preventTransparency
|
||||
? size - 4
|
||||
: size + 4,
|
||||
height: preventTransparency
|
||||
? size - 4
|
||||
: size + 4,
|
||||
backgroundColor,
|
||||
borderRadius: 9999
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{
|
||||
children || (
|
||||
<INatIcon
|
||||
name={icon}
|
||||
size={size}
|
||||
color={color || colors.darkGray}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</View>
|
||||
{ content }
|
||||
</Pressable>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -722,6 +722,12 @@ Most-faved = Most faved
|
||||
# created by the viewer. Should be 16 characters or fewer or it will be ellipsized.
|
||||
MY-CONTENT--notifications = MY CONTENT
|
||||
My-Observations = My Observations
|
||||
# Label for the bottom tab that shows your observations. Feel free to be
|
||||
# flexible in translating this to keep it as short as possible. "My
|
||||
# Observations" would be our preference in English, but it won't really fit,
|
||||
# so we went with "Me". You have about ~7-20 characters before it gets cut
|
||||
# off on the smallest screen sizes.
|
||||
My-Observations--bottom-tab = Me
|
||||
Native = Native
|
||||
Native-to-place = Native to { $place }
|
||||
Navigates-to-AI-camera = Navigates to AI camera
|
||||
@@ -785,7 +791,12 @@ NOTES = NOTES
|
||||
# Label for section in ObsDetails with notes/description of observation
|
||||
Notes = Notes
|
||||
NOTIFICATIONS = NOTIFICATIONS
|
||||
Notifications = Notifications
|
||||
# Label for the bottom tab that shows notifications. Feel free to be flexible
|
||||
# in translating this to keep it as short as possible. "Notifications" would
|
||||
# be our preference in English, but it won't really fit, so we went
|
||||
# with "Activity". You have about ~7-20 characters before it gets cut off on
|
||||
# the smallest screen sizes.
|
||||
Notifications--bottom-tab = Activity
|
||||
# notification when someone adds a comment to your observation
|
||||
notifications-user-added-comment-to-observation-by-you = <0>{ $userName }</0> added a comment to an observation by you
|
||||
# notification when someone adds an identification to your observation
|
||||
@@ -857,7 +868,6 @@ Once-you-create-and-upload-observations = Once you create & upload observations,
|
||||
One-last-step = One last step!
|
||||
# Adjective, as in geoprivacy
|
||||
Open = Open
|
||||
Open-drawer = Open drawer
|
||||
OPEN-EMAIL = OPEN EMAIL
|
||||
Open-menu = Open menu.
|
||||
# Text for a button that opens the operating system Settings app
|
||||
|
||||
@@ -432,6 +432,7 @@
|
||||
"Most-faved": "Most faved",
|
||||
"MY-CONTENT--notifications": "MY CONTENT",
|
||||
"My-Observations": "My Observations",
|
||||
"My-Observations--bottom-tab": "Me",
|
||||
"Native": "Native",
|
||||
"Native-to-place": "Native to { $place }",
|
||||
"Navigates-to-AI-camera": "Navigates to AI camera",
|
||||
@@ -475,7 +476,7 @@
|
||||
"NOTES": "NOTES",
|
||||
"Notes": "Notes",
|
||||
"NOTIFICATIONS": "NOTIFICATIONS",
|
||||
"Notifications": "Notifications",
|
||||
"Notifications--bottom-tab": "Activity",
|
||||
"notifications-user-added-comment-to-observation-by-you": "<0>{ $userName }</0> added a comment to an observation by you",
|
||||
"notifications-user-added-identification-to-observation-by-you": "<0>{ $userName }</0> added an identification to an observation by you",
|
||||
"notifications-user1-added-comment-to-observation-by-user2": "<0>{ $user1 }</0> added a comment to an observation by { $user2 }",
|
||||
@@ -519,7 +520,6 @@
|
||||
"Once-you-create-and-upload-observations": "Once you create & upload observations, other members of our community can add identifications to help your observations reach research grade.",
|
||||
"One-last-step": "One last step!",
|
||||
"Open": "Open",
|
||||
"Open-drawer": "Open drawer",
|
||||
"OPEN-EMAIL": "OPEN EMAIL",
|
||||
"Open-menu": "Open menu.",
|
||||
"OPEN-SETTINGS": "OPEN SETTINGS",
|
||||
|
||||
@@ -722,6 +722,12 @@ Most-faved = Most faved
|
||||
# created by the viewer. Should be 16 characters or fewer or it will be ellipsized.
|
||||
MY-CONTENT--notifications = MY CONTENT
|
||||
My-Observations = My Observations
|
||||
# Label for the bottom tab that shows your observations. Feel free to be
|
||||
# flexible in translating this to keep it as short as possible. "My
|
||||
# Observations" would be our preference in English, but it won't really fit,
|
||||
# so we went with "Me". You have about ~7-20 characters before it gets cut
|
||||
# off on the smallest screen sizes.
|
||||
My-Observations--bottom-tab = Me
|
||||
Native = Native
|
||||
Native-to-place = Native to { $place }
|
||||
Navigates-to-AI-camera = Navigates to AI camera
|
||||
@@ -785,7 +791,12 @@ NOTES = NOTES
|
||||
# Label for section in ObsDetails with notes/description of observation
|
||||
Notes = Notes
|
||||
NOTIFICATIONS = NOTIFICATIONS
|
||||
Notifications = Notifications
|
||||
# Label for the bottom tab that shows notifications. Feel free to be flexible
|
||||
# in translating this to keep it as short as possible. "Notifications" would
|
||||
# be our preference in English, but it won't really fit, so we went
|
||||
# with "Activity". You have about ~7-20 characters before it gets cut off on
|
||||
# the smallest screen sizes.
|
||||
Notifications--bottom-tab = Activity
|
||||
# notification when someone adds a comment to your observation
|
||||
notifications-user-added-comment-to-observation-by-you = <0>{ $userName }</0> added a comment to an observation by you
|
||||
# notification when someone adds an identification to your observation
|
||||
@@ -857,7 +868,6 @@ Once-you-create-and-upload-observations = Once you create & upload observations,
|
||||
One-last-step = One last step!
|
||||
# Adjective, as in geoprivacy
|
||||
Open = Open
|
||||
Open-drawer = Open drawer
|
||||
OPEN-EMAIL = OPEN EMAIL
|
||||
Open-menu = Open menu.
|
||||
# Text for a button that opens the operating system Settings app
|
||||
|
||||
@@ -23,14 +23,26 @@ type Props = {
|
||||
const CustomTabBar = ( { tabs }: Props ): Node => {
|
||||
const tabList = tabs.map( tab => <NavButton {...tab} key={tab.testID} /> );
|
||||
|
||||
tabList.splice( -2, 0, <AddObsButton key="AddObsButton" /> );
|
||||
tabList.splice(
|
||||
-2,
|
||||
0,
|
||||
// Absolutely position the AddObsButton so it can float outside of the tab
|
||||
// bar
|
||||
(
|
||||
<View className="w-[69px] h-[60px] mx-3" key="CustomTabBar-AddObs">
|
||||
<View className="absolute top-[-13px]">
|
||||
<AddObsButton key="AddObsButton" />
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
);
|
||||
|
||||
const insets = useSafeAreaInsets( );
|
||||
|
||||
return (
|
||||
<View
|
||||
className={classNames(
|
||||
"flex-row bg-white justify-evenly items-center p-1 m-0",
|
||||
"flex-row bg-white justify-evenly p-1 m-0",
|
||||
{ "pb-5": insets.bottom > 0 }
|
||||
)}
|
||||
style={DROP_SHADOW}
|
||||
|
||||
@@ -43,7 +43,7 @@ const CustomTabBarContainer = ( { navigation }: Props ): Node => {
|
||||
{
|
||||
icon: "hamburger-menu",
|
||||
testID: DRAWER_ID,
|
||||
accessibilityLabel: t( "Open-drawer" ),
|
||||
accessibilityLabel: t( "Menu" ),
|
||||
accessibilityHint: t( "Opens-the-side-drawer-menu" ),
|
||||
size: 32,
|
||||
onPress: ( ) => {
|
||||
@@ -66,7 +66,7 @@ const CustomTabBarContainer = ( { navigation }: Props ): Node => {
|
||||
icon: "person",
|
||||
userIconUri: User.uri( currentUser ),
|
||||
testID: "NavButton.personIcon",
|
||||
accessibilityLabel: t( "Observations" ),
|
||||
accessibilityLabel: t( "My-Observations--bottom-tab" ),
|
||||
accessibilityHint: t( "Navigates-to-your-observations" ),
|
||||
size: 40,
|
||||
onPress: ( ) => {
|
||||
@@ -77,7 +77,7 @@ const CustomTabBarContainer = ( { navigation }: Props ): Node => {
|
||||
{
|
||||
icon: "notifications-bell",
|
||||
testID: SCREEN_NAME_NOTIFICATIONS,
|
||||
accessibilityLabel: t( "Notifications" ),
|
||||
accessibilityLabel: t( "Notifications--bottom-tab" ),
|
||||
accessibilityHint: t( "Navigates-to-notifications" ),
|
||||
size: 32,
|
||||
onPress: ( ) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @flow
|
||||
import { INatIconButton, UserIcon } from "components/SharedComponents";
|
||||
import { Pressable } from "components/styledComponents";
|
||||
import { Body3, INatIconButton, UserIcon } from "components/SharedComponents";
|
||||
import { Pressable, View } from "components/styledComponents";
|
||||
import NotificationsIconContainer from "navigation/BottomTabNavigator/NotificationsIconContainer";
|
||||
import * as React from "react";
|
||||
import colors from "styles/tailwindColors";
|
||||
@@ -28,67 +28,73 @@ const NavButton = ( {
|
||||
active,
|
||||
accessibilityLabel,
|
||||
accessibilityHint,
|
||||
accessibilityRole = "tab",
|
||||
width = 44,
|
||||
height = 44
|
||||
}: Props ): React.Node => {
|
||||
/* eslint-disable react/jsx-props-no-spreading */
|
||||
const sharedProps = {
|
||||
testID,
|
||||
onPress,
|
||||
accessibilityRole,
|
||||
accessibilityLabel,
|
||||
accessibilityHint,
|
||||
accessibilityState: {
|
||||
selected: active,
|
||||
expanded: active,
|
||||
disabled: false
|
||||
},
|
||||
width,
|
||||
height
|
||||
};
|
||||
|
||||
const notificationProps = {
|
||||
testID,
|
||||
onPress,
|
||||
accessibilityRole,
|
||||
accessibilityLabel,
|
||||
accessibilityHint,
|
||||
width,
|
||||
height
|
||||
};
|
||||
|
||||
let iconComponent;
|
||||
if ( userIconUri ) {
|
||||
return (
|
||||
<Pressable
|
||||
iconComponent = (
|
||||
<View
|
||||
className="flex items-center justify-center"
|
||||
{...sharedProps}
|
||||
>
|
||||
<UserIcon uri={userIconUri} active={active} />
|
||||
</Pressable>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
if ( icon === "notifications-bell" ) {
|
||||
return (
|
||||
} else if ( icon === "notifications-bell" ) {
|
||||
iconComponent = (
|
||||
<NotificationsIconContainer
|
||||
icon={icon}
|
||||
size={size}
|
||||
active={active}
|
||||
{...notificationProps}
|
||||
{...sharedProps}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
iconComponent = (
|
||||
<INatIconButton
|
||||
icon={icon}
|
||||
iconOnly
|
||||
color={active
|
||||
? colors.inatGreen
|
||||
: colors.darkGray}
|
||||
size={size}
|
||||
{...sharedProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<INatIconButton
|
||||
icon={icon}
|
||||
color={active
|
||||
? colors.inatGreen
|
||||
: colors.darkGray}
|
||||
size={size}
|
||||
{...sharedProps}
|
||||
/>
|
||||
<Pressable
|
||||
className="flex-column items-center w-[20%] justify-end"
|
||||
onPress={onPress}
|
||||
key={`NavButton-${accessibilityLabel}`}
|
||||
accessibilityLabel={accessibilityLabel}
|
||||
accessibilityRole="tab"
|
||||
accessibilityHint={accessibilityHint}
|
||||
accessibilityState={{
|
||||
selected: active,
|
||||
disabled: false
|
||||
}}
|
||||
>
|
||||
{iconComponent}
|
||||
<Body3
|
||||
numberOfLines={1}
|
||||
className={active
|
||||
? "text-inatGreen"
|
||||
: "text-darkGray"}
|
||||
maxFontSizeMultiplier={1.2}
|
||||
>
|
||||
{accessibilityLabel}
|
||||
</Body3>
|
||||
</Pressable>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// @flow
|
||||
import classnames from "classnames";
|
||||
import { INatIcon, INatIconButton } from "components/SharedComponents";
|
||||
import {
|
||||
Pressable, View
|
||||
} from "components/styledComponents";
|
||||
import { View } from "components/styledComponents";
|
||||
import * as React from "react";
|
||||
import colors from "styles/tailwindColors";
|
||||
|
||||
@@ -11,11 +9,7 @@ type Props = {
|
||||
unread: boolean,
|
||||
icon: string,
|
||||
testID: string,
|
||||
onPress: Function,
|
||||
active:boolean,
|
||||
accessibilityLabel: string,
|
||||
accessibilityRole?: string,
|
||||
accessibilityHint?: string,
|
||||
size: number,
|
||||
width?: number,
|
||||
height?: number
|
||||
@@ -26,33 +20,20 @@ const NotificationsIcon = ( {
|
||||
testID,
|
||||
size,
|
||||
icon,
|
||||
onPress,
|
||||
active,
|
||||
accessibilityLabel,
|
||||
accessibilityHint,
|
||||
accessibilityRole = "tab",
|
||||
width,
|
||||
height
|
||||
}: Props ): React.Node => {
|
||||
/* eslint-disable react/jsx-props-no-spreading */
|
||||
const sharedProps = {
|
||||
testID,
|
||||
onPress,
|
||||
accessibilityRole,
|
||||
accessibilityLabel,
|
||||
accessibilityHint,
|
||||
accessibilityState: {
|
||||
selected: active,
|
||||
expanded: active,
|
||||
disabled: false
|
||||
},
|
||||
width,
|
||||
height
|
||||
};
|
||||
|
||||
if ( unread ) {
|
||||
return (
|
||||
<Pressable
|
||||
<View
|
||||
className="flex items-center justify-center"
|
||||
{...sharedProps}
|
||||
>
|
||||
@@ -88,7 +69,7 @@ const NotificationsIcon = ( {
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
</Pressable>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -100,6 +81,7 @@ const NotificationsIcon = ( {
|
||||
: colors.darkGray}
|
||||
size={size}
|
||||
{...sharedProps}
|
||||
iconOnly
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,11 +13,7 @@ import useStore from "stores/useStore";
|
||||
type Props = {
|
||||
testID: string,
|
||||
icon: string,
|
||||
onPress: Function,
|
||||
active:boolean,
|
||||
accessibilityLabel: string,
|
||||
accessibilityRole?: string,
|
||||
accessibilityHint?: string,
|
||||
size: number,
|
||||
width?: number,
|
||||
height?: number
|
||||
@@ -27,11 +23,7 @@ const NotificationsIconContainer = ( {
|
||||
testID,
|
||||
size,
|
||||
icon,
|
||||
onPress,
|
||||
active,
|
||||
accessibilityLabel,
|
||||
accessibilityHint,
|
||||
accessibilityRole = "tab",
|
||||
width,
|
||||
height
|
||||
}: Props ): Node => {
|
||||
@@ -73,10 +65,6 @@ const NotificationsIconContainer = ( {
|
||||
active={active}
|
||||
size={size}
|
||||
testID={testID}
|
||||
onPress={onPress}
|
||||
accessibilityRole={accessibilityRole}
|
||||
accessibilityLabel={accessibilityLabel}
|
||||
accessibilityHint={accessibilityHint}
|
||||
width={width}
|
||||
height={height}
|
||||
/>
|
||||
|
||||
@@ -102,7 +102,7 @@ async function navigateToRootExplore( ) {
|
||||
const welcomeBack = await screen.findByText( /Welcome back/ );
|
||||
await waitFor( ( ) => expect( welcomeBack ).toBeVisible( ) );
|
||||
const tabBar = await screen.findByTestId( "CustomTabBar" );
|
||||
const exploreButton = await within( tabBar ).findByLabelText( "Explore" );
|
||||
const exploreButton = await within( tabBar ).findByText( "Explore" );
|
||||
await actor.press( exploreButton );
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -36,14 +36,18 @@ exports[`INatIconButton renders correctly 1`] = `
|
||||
style={
|
||||
[
|
||||
{
|
||||
"alignItems": "center",
|
||||
"height": 44,
|
||||
"justifyContent": "center",
|
||||
"opacity": 1,
|
||||
"width": 44,
|
||||
},
|
||||
{
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center",
|
||||
},
|
||||
false,
|
||||
undefined,
|
||||
{
|
||||
"opacity": 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
|
||||
@@ -447,14 +447,18 @@ exports[`UploadStatus displays start icon when upload is unsynced and not queued
|
||||
style={
|
||||
[
|
||||
{
|
||||
"alignItems": "center",
|
||||
"height": 44,
|
||||
"justifyContent": "center",
|
||||
"opacity": 1,
|
||||
"width": 44,
|
||||
},
|
||||
{
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center",
|
||||
},
|
||||
false,
|
||||
undefined,
|
||||
{
|
||||
"opacity": 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
testID="UploadIcon.start.undefined"
|
||||
|
||||
@@ -460,14 +460,18 @@ exports[`TaxonResult should render correctly 1`] = `
|
||||
style={
|
||||
[
|
||||
{
|
||||
"alignItems": "center",
|
||||
"height": 44,
|
||||
"justifyContent": "center",
|
||||
"opacity": 1,
|
||||
"width": 44,
|
||||
},
|
||||
{
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center",
|
||||
},
|
||||
false,
|
||||
undefined,
|
||||
{
|
||||
"opacity": 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
@@ -546,18 +550,22 @@ exports[`TaxonResult should render correctly 1`] = `
|
||||
style={
|
||||
[
|
||||
{
|
||||
"alignItems": "center",
|
||||
"height": 44,
|
||||
"justifyContent": "center",
|
||||
"opacity": 1,
|
||||
"width": 44,
|
||||
},
|
||||
{
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center",
|
||||
},
|
||||
false,
|
||||
[
|
||||
{
|
||||
"marginLeft": 8,
|
||||
},
|
||||
],
|
||||
{
|
||||
"opacity": 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
testID="undefined.checkmark"
|
||||
|
||||
Reference in New Issue
Block a user