Skip to content

Commit

Permalink
refactor(header): Update TopBarIconButtonV2 and refactor headers comp…
Browse files Browse the repository at this point in the history
…onents (#5276)

### Description
This is a refactor of the previous TopBarIconButton which has
inconsistent behavior throughout the app, particularly in regards to
button padding and ripple effect on Android. This PR also changes four
files to use this new component:
1. src/components/AccountCircleButton.tsx
2. src/home/NotificationBell.tsx
3. src/components/QrScanButton.tsx
4. src/components/PointsButton.tsx - I did update the size here from
default size (16) to match the size of the other icons (24)

### Test plan

- Screenshot below which shows the size of each component with red
background (although this commit does not have background color):

![image](https://github.com/valora-inc/wallet/assets/24781710/6b52404d-0fd0-430f-b68f-0769dadfffd5)

- Also passes all tests
[here](![image](https://github.com/valora-inc/wallet/assets/24781710/6e3445fa-f1e8-43eb-9842-c0b56c44bd50))

### Related issues

- Refactor
[ACT-1134](https://linear.app/valora/issue/ACT-1134/create-new-topbarbuttons-text-icon)

### Backwards compatibility

Yes

### Network scalability

If a new NetworkId and/or Network are added in the future, the changes
in this PR will:

- [X] Continue to work without code changes, OR trigger a compilation
error (guaranteeing we find it when a new network is added)
  • Loading branch information
chriskeating603 committed Apr 24, 2024
1 parent 38c8d1b commit c606a83
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 84 deletions.
33 changes: 9 additions & 24 deletions src/components/AccountCircleButton.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,30 @@
import React from 'react'
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
import { StyleProp, ViewStyle } from 'react-native'
import { HomeEvents } from 'src/analytics/Events'
import ValoraAnalytics from 'src/analytics/ValoraAnalytics'
import Touchable from 'src/components/Touchable'
import AccountCircle from 'src/icons/AccountCircle'
import { navigate } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
import { Spacing } from 'src/styles/styles'
import { TopBarIconButtonV2 } from 'src/navigator/TopBarIconButtonV2'

interface Props {
style?: StyleProp<ViewStyle>
size?: number
testID?: string
}

export default function AccountCircleButton({ style, size, testID }: Props) {
export default function AccountCircleButton({ testID, size, style }: Props) {
const onPress = () => {
ValoraAnalytics.track(HomeEvents.account_circle_tapped)
navigate(Screens.ProfileMenu)
}

return (
<View style={styles.container}>
<Touchable
testID={testID}
onPress={onPress}
style={[style, styles.button]}
borderRadius={Spacing.Thick24}
>
<AccountCircle size={size} />
</Touchable>
</View>
<TopBarIconButtonV2
icon={<AccountCircle size={size} />}
testID={testID}
onPress={onPress}
style={style}
/>
)
}

const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
},
button: {
padding: Spacing.Small12,
},
})
8 changes: 4 additions & 4 deletions src/components/PointsButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ import ValoraAnalytics from 'src/analytics/ValoraAnalytics'
import AttentionIcon from 'src/icons/Attention'
import { navigate } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
import { TopBarIconButton } from 'src/navigator/TopBarButton'
import { TopBarIconButtonV2 } from 'src/navigator/TopBarIconButtonV2'

interface Props {
style?: StyleProp<ViewStyle>
size?: number
testID?: string
}

export default function PointsButton({ style, size, testID }: Props) {
export default function PointsButton({ testID, size, style }: Props) {
const onPress = () => {
ValoraAnalytics.track(PointsEvents.points_screen_open)
navigate(Screens.PointsHome)
}

return (
<TopBarIconButton
testID={testID}
<TopBarIconButtonV2
icon={<AttentionIcon size={size} />}
testID={testID}
onPress={onPress}
style={style}
/>
Expand Down
33 changes: 9 additions & 24 deletions src/components/QrScanButton.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,30 @@
import React from 'react'
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
import { StyleProp, ViewStyle } from 'react-native'
import { QrScreenEvents } from 'src/analytics/Events'
import ValoraAnalytics from 'src/analytics/ValoraAnalytics'
import Touchable from 'src/components/Touchable'
import ScanIcon from 'src/icons/ScanIcon'
import { navigate } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
import { Spacing } from 'src/styles/styles'
import { TopBarIconButtonV2 } from 'src/navigator/TopBarIconButtonV2'

interface Props {
style?: StyleProp<ViewStyle>
size?: number
testID?: string
}

export default function QrScanButton({ style, size, testID }: Props) {
export default function QrScanButton({ testID, size, style }: Props) {
const onPress = () => {
ValoraAnalytics.track(QrScreenEvents.qr_scanner_open)
navigate(Screens.QRNavigator, { screen: Screens.QRScanner })
}

return (
<View style={styles.container}>
<Touchable
testID={testID}
onPress={onPress}
style={[style, styles.button]}
borderRadius={Spacing.Thick24}
>
<ScanIcon size={size} />
</Touchable>
</View>
<TopBarIconButtonV2
icon={<ScanIcon size={size} />}
testID={testID}
onPress={onPress}
style={style}
/>
)
}

const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
},
button: {
padding: Spacing.Small12,
},
})
37 changes: 10 additions & 27 deletions src/home/NotificationBell.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,37 @@
import React from 'react'
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
import { StyleProp, ViewStyle } from 'react-native'
import { HomeEvents } from 'src/analytics/Events'
import ValoraAnalytics from 'src/analytics/ValoraAnalytics'
import Touchable from 'src/components/Touchable'
import { useNotifications } from 'src/home/NotificationCenter'
import NotificationBellIcon from 'src/icons/NotificationBellIcon'
import { navigate } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
import { TopBarIconButtonV2 } from 'src/navigator/TopBarIconButtonV2'
import colors from 'src/styles/colors'
import { Spacing } from 'src/styles/styles'

interface Props {
style?: StyleProp<ViewStyle>
size?: number
testID?: string
}

export default function NotificationBell({ style, size, testID }: Props) {
export default function NotificationBell({ testID, size, style }: Props) {
const notifications = useNotifications()

const hasNotifications = notifications.length > 0
const notificationMark = hasNotifications ? colors.primary : undefined

const onPress = () => {
ValoraAnalytics.track(HomeEvents.notification_bell_pressed, {
hasNotifications,
})
ValoraAnalytics.track(HomeEvents.notification_bell_pressed, { hasNotifications })
navigate(Screens.NotificationCenter)
}

return (
<View style={styles.container}>
<Touchable
testID={testID}
onPress={onPress}
style={[style, styles.button]}
borderRadius={Spacing.Thick24}
>
<NotificationBellIcon size={size} notificationMark={notificationMark} />
</Touchable>
</View>
<TopBarIconButtonV2
icon={<NotificationBellIcon size={size} notificationMark={notificationMark} />}
testID={testID}
onPress={onPress}
style={style}
/>
)
}

const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
},
button: {
padding: Spacing.Small12,
},
})
6 changes: 3 additions & 3 deletions src/navigator/Headers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import CancelButton from 'src/components/CancelButton'
import CloseButton from 'src/components/CloseButton'
import CurrencyDisplay from 'src/components/CurrencyDisplay'
import LegacyTokenDisplay from 'src/components/LegacyTokenDisplay'
import PointsButton from 'src/components/PointsButton'
import QrScanButton from 'src/components/QrScanButton'
import TokenDisplay from 'src/components/TokenDisplay'
import NotificationBell from 'src/home/NotificationBell'
Expand All @@ -16,15 +17,14 @@ import BackChevronCentered from 'src/icons/BackChevronCentered'
import { navigateBack } from 'src/navigator/NavigationService'
import { TopBarIconButton } from 'src/navigator/TopBarButton'
import DisconnectBanner from 'src/shared/DisconnectBanner'
import { getFeatureGate } from 'src/statsig'
import { StatsigFeatureGates } from 'src/statsig/types'
import colors from 'src/styles/colors'
import { typeScale } from 'src/styles/fonts'
import { Spacing } from 'src/styles/styles'
import { useTokenInfoByCurrency } from 'src/tokens/hooks'
import { TokenBalance } from 'src/tokens/slice'
import { Currency } from 'src/utils/currencies'
import { getFeatureGate } from 'src/statsig'
import { StatsigFeatureGates } from 'src/statsig/types'
import PointsButton from 'src/components/PointsButton'

export const noHeader: NativeStackNavigationOptions = {
headerShown: false,
Expand Down
3 changes: 1 addition & 2 deletions src/navigator/TopBarButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ export type TopBarIconButtonProps = CommonProps & {
}

/**
* Please avoid use in new header icons
* TODO: ACT-1134 alternative component
* Please avoid use in new header icons - use TopBarIconButtonV2 instead
* @deprecated
*/
export function TopBarIconButton(props: TopBarIconButtonProps) {
Expand Down
17 changes: 17 additions & 0 deletions src/navigator/TopBarIconButtonV2.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { fireEvent, render } from '@testing-library/react-native'
import * as React from 'react'
import { Text } from 'react-native'
import { TopBarIconButtonV2 } from 'src/navigator/TopBarIconButtonV2'
const testID = 'button'

describe('TopBarIconButtonV2', () => {
it('renders correctly with given props', () => {
const onPress = jest.fn()
const { getByTestId } = render(
<TopBarIconButtonV2 testID={testID} icon={<Text>icon</Text>} onPress={onPress} />
)
expect(getByTestId(testID)).toBeTruthy()
fireEvent.press(getByTestId(testID))
expect(onPress).toHaveBeenCalled()
})
})
84 changes: 84 additions & 0 deletions src/navigator/TopBarIconButtonV2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import * as React from 'react'
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
import { AnalyticsEventType, AnalyticsPropertiesList } from 'src/analytics/Properties'
import ValoraAnalytics from 'src/analytics/ValoraAnalytics'
import Touchable from 'src/components/Touchable'
import { Spacing } from 'src/styles/styles'
import variables from 'src/styles/variables'

interface CommonProps {
disabled?: boolean
testID?: string
onPress: () => void
eventName?: AnalyticsEventType
eventProperties?: AnalyticsPropertiesList[AnalyticsEventType]
style?: StyleProp<ViewStyle>
}

type WrapperProps = CommonProps & {
children: JSX.Element
}

function Wrapper({
eventName,
onPress,
disabled,
testID,
children,
style,
eventProperties,
}: WrapperProps) {
const onPressLocal = React.useCallback(() => {
if (eventName) {
eventProperties
? ValoraAnalytics.track(eventName, eventProperties)
: ValoraAnalytics.track(eventName)
}
onPress()
}, [onPress, eventName])

return (
<Touchable
disabled={disabled}
onPress={onPressLocal}
borderless={true}
hitSlop={variables.iconHitslop}
style={style}
>
{children}
</Touchable>
)
}

type TopBarIconButtonV2Props = CommonProps & {
icon: JSX.Element
containerStyle?: ViewStyle
size?: number
}

export function TopBarIconButtonV2(props: TopBarIconButtonV2Props) {
return (
<Wrapper {...props}>
<View style={[styles.container, props.containerStyle]}>
<Touchable
testID={props.testID}
onPress={props.onPress}
style={[styles.button, props.style]}
borderRadius={Spacing.Thick24}
>
{props.icon}
</Touchable>
</View>
</Wrapper>
)
}

const styles = StyleSheet.create({
button: {
padding: Spacing.Small12,
},
container: {
justifyContent: 'center',
alignItems: 'center',
},
})

0 comments on commit c606a83

Please sign in to comment.