Skip to content

Commit

Permalink
feature/9733-VAIconWithTextMigration (#9734)
Browse files Browse the repository at this point in the history
Co-authored-by: Tim Wright <[email protected]>
  • Loading branch information
Sparowhawk and timwright12 authored Oct 23, 2024
1 parent cde2cc8 commit 1edd172
Show file tree
Hide file tree
Showing 33 changed files with 124 additions and 205 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { ReactComponent as ChevronLeft} from '@componentsDocs/VAIcon/svgs/Chevro
import { ReactComponent as ChevronRight} from '@componentsDocs/VAIcon/svgs/ChevronRight.svg';
import { ReactComponent as CircleCheckMark} from '@componentsDocs/VAIcon/svgs/CircleCheckMark.svg';
import { ReactComponent as Compose} from '@componentsDocs/VAIcon/svgs/Compose.svg';
import { ReactComponent as Ellipsis} from '@componentsDocs/VAIcon/svgs/Ellipsis.svg';
import { ReactComponent as ExclamationTriangle} from '@componentsDocs/VAIcon/svgs/ExclamationTriangle.svg';
import { ReactComponent as ExternalLink} from '@componentsDocs/VAIcon/svgs/ExternalLink.svg';
import { ReactComponent as Folder} from '@componentsDocs/VAIcon/svgs/Folder.svg';
Expand Down Expand Up @@ -41,7 +40,6 @@ Check Mark in Circle | <CircleCheckMark className="icons"/> | CircleCheckMark.s
Chevron Left | <ChevronLeft className="icons"/> | ChevronLeft.svg
Chevron Right | <ChevronRight className="icons iconsStroke"/> | ChevronRight.svg
Compose | <Compose className="icons"/> | Compose.svg
Ellipsis | <Ellipsis className="icons"/> | Ellipsis.svg
Exclamation Triangle | <ExclamationTriangle className="icons"/> | ExclamationTriangle.svg
External Link | <ExternalLink className="icons"/> | ExternalLink.svg
Folder | <Folder className="icons"/> | Folder.svg
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { screen } from '@testing-library/react-native'

import { context, render } from 'testUtils'

import VAIconWithText from './VAIconWithText'
import IconWithText from './IconWithText'

context('VAIconWithText', () => {
beforeEach(() => {
render(<VAIconWithText name="HomeSelected" label="Home" labelA11y="A11y label" testID="HomeSelected" />)
render(<IconWithText name="Home" label="Home" labelA11y="A11y label" testID="HomeSelected" />)
})

it('renders label, a11yLabel, and icon', () => {
Expand Down
48 changes: 48 additions & 0 deletions VAMobile/src/components/IconWithText/IconWithText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { FC } from 'react'

import { Icon, IconProps } from '@department-of-veterans-affairs/mobile-component-library/src/components/Icon/Icon'

import { Box, ColorVariant, TextView, TextViewProps } from 'components'

export type IconWithTextProps = IconProps & {
/** label to display below icon */
label: string
/** label color variant. default is textWithIconButton */
labelColor?: ColorVariant
/** optional a11y label */
labelA11y?: string
/** optional margin between text and icon */
mt?: number
}

/**
* Display icon with text label underneath
*
* @returns IconWithText component
*/
const IconWithText: FC<IconWithTextProps> = ({ label, labelColor, labelA11y, mt, ...iconProps }) => {
const props: IconProps = {
...iconProps,
fill: iconProps.fill || 'link',
height: iconProps.height || 24,
width: iconProps.width || 24,
preventScaling: iconProps.preventScaling ?? true,
}

const textProps: TextViewProps = {
variant: 'textWithIconButton',
mt: mt || 3, // 6px total combined with line height
color: labelColor || 'textWithIconButton',
accessibilityLabel: labelA11y,
allowFontScaling: false,
}

return (
<Box alignItems="center">
<Icon {...props} />
<TextView {...textProps}>{label}</TextView>
</Box>
)
}

export default IconWithText
2 changes: 2 additions & 0 deletions VAMobile/src/components/IconWithText/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './IconWithText'
export { default } from './IconWithText'
22 changes: 10 additions & 12 deletions VAMobile/src/components/Menu/MenuView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import React, { FC, useEffect, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { Dimensions, Pressable, StyleProp, View, ViewStyle } from 'react-native'

import { Icon } from '@department-of-veterans-affairs/mobile-component-library'
import { IconProps } from '@department-of-veterans-affairs/mobile-component-library/src/components/Icon/Icon'

import IconWithText from 'components/IconWithText'
import TextView from 'components/TextView'
import VAIcon, { VA_ICON_MAP } from 'components/VAIcon'
import VAIconWithText from 'components/VAIconWithText'
import { NAMESPACE } from 'constants/namespaces'
import { VAIconColors, VATextColors } from 'styles/theme'
import { VATextColors } from 'styles/theme'
import { useTheme } from 'utils/hooks'
import { isIOS } from 'utils/platform'

Expand All @@ -28,12 +30,10 @@ export type MenuItemActionsType = {
actionText: string
/** adds a divider after the action*/
addDivider: boolean
/** name of the icon to show */
iconName?: keyof typeof VA_ICON_MAP
/** icon props to show */
iconProps?: IconProps
/** method to */
onPress?: () => void
/** color for the menu icon */
iconColor?: keyof VAIconColors
/** color for the menu text */
textColor?: keyof VATextColors
/** action accessibility label */
Expand Down Expand Up @@ -100,7 +100,7 @@ const MenuView: FC<MenuViewProps> = ({ actions }) => {
// gets the action passed down to the menu and creates the menu actions
const getActionsForMenu = () => {
return actions.map((item, index) => {
const { iconName, actionText, accessibilityLabel, iconColor, textColor } = item
const { iconProps, actionText, accessibilityLabel, textColor } = item
const onPressMenu = () => {
hideMenu()

Expand All @@ -121,9 +121,7 @@ const MenuView: FC<MenuViewProps> = ({ actions }) => {
viewStyle={menuStyle}
underlayColor={currentTheme.colors.buttonBackground.overFlowMenuButton}
accessibilityLabel={accessibilityLabel}>
{iconName && (
<VAIcon name={iconName} fill={iconColor ? iconColor : 'defaultMenuItem'} height={24} width={24} />
)}
{iconProps && <Icon {...iconProps} />}
<TextView variant={'MobileBody'} ml={10} color={textColor ? textColor : undefined} accessible={false}>
{actionText}
</TextView>
Expand All @@ -139,7 +137,7 @@ const MenuView: FC<MenuViewProps> = ({ actions }) => {
<>
<ElementToStick ref={elementRef} style={elementToStickStyle} />
<Pressable onPress={showMenu} style={launchBtnStyle} accessibilityLabel={'menu'} accessibilityRole={'button'}>
<VAIconWithText name="Ellipsis" label={t('more')} />
<IconWithText name="MoreHoriz" fill={currentTheme.colors.icon.active} label={t('more')} />
</Pressable>

<Menu ref={setMenuRef} style={{ backgroundColor: currentTheme.colors.background.menu }}>
Expand Down
32 changes: 26 additions & 6 deletions VAMobile/src/components/NavigationTabBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ import { changeNavigationBarColor } from 'utils/rnNativeUIUtilities'
import { themeFn } from 'utils/theme'

import Box from './Box'
import { VA_ICON_MAP } from './VAIcon'
import VAIconWithText, { VAIconWithTextProps } from './VAIconWithText/VAIconWithText'
import IconWithText, { IconWithTextProps } from './IconWithText'

type TabBarRoute = {
key: string
Expand Down Expand Up @@ -106,11 +105,32 @@ const NavigationTabBar: FC<NavigationTabBarProps> = ({ state, navigation, transl
accessible: true,
}

const iconProps: VAIconWithTextProps = {
name: `${routeName}${isFocused ? 'Selected' : 'Unselected'}` as keyof typeof VA_ICON_MAP,
fill: isFocused ? 'active' : 'inactive',
const iconProps: IconWithTextProps = {
name: 'Home',
fill: isFocused ? theme.colors.icon.active : theme.colors.icon.inactive,
label: routeName,
labelColor: isFocused ? 'textWithIconButton' : 'textWithIconButtonInactive',
height: 24,
width: 24,
}
switch (routeName) {
case 'Home':
iconProps.height = 28
iconProps.width = 28
iconProps.mt = -1
iconProps.name = isFocused ? 'Home' : 'HomeOutlined'
break
case 'Health':
iconProps.name = isFocused ? 'MedicalServices' : 'MedicalServicesOutlined'
break
case 'Benefits':
iconProps.name = isFocused ? 'Description' : 'DescriptionOutlined'
break
case 'Payments':
iconProps.name = isFocused ? 'RequestQuote' : 'RequestQuoteOutlined'
break
default:
iconProps.name = 'Home'
}

return (
Expand All @@ -121,7 +141,7 @@ const NavigationTabBar: FC<NavigationTabBarProps> = ({ state, navigation, transl
{...a11yValueProp({ text: t('listPosition', { position: index + 1, total: state.routes.length }) })}>
<Box flex={1} display="flex" flexDirection="column" mt={7}>
<Box alignSelf="center" position="absolute" mt={theme.dimensions.buttonBorderWidth}>
<VAIconWithText {...iconProps} />
<IconWithText {...iconProps} />
</Box>
</Box>
</TouchableWithoutFeedback>
Expand Down
2 changes: 1 addition & 1 deletion VAMobile/src/components/Templates/CategoryLanding.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ context('CategoryLandingTemplate', () => {
})

it('should render a header button if passed in', () => {
initializeTestInstance('', { label: 'test', icon: { name: 'HomeSelected' }, onPress: onPressSpy })
initializeTestInstance('', { label: 'test', icon: { name: 'HomeOutlined' }, onPress: onPressSpy })
fireEvent.press(screen.getByRole('button', { name: 'test' }))
expect(onPressSpy).toHaveBeenCalled()
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ context('FeatureLandingAndChildTemplate', () => {
})

it('should render a header button and onPress if passed in', () => {
initializeTestInstance({ label: 'test', icon: { name: 'HomeSelected' }, onPress: onPressSpy })
initializeTestInstance({ label: 'test', icon: { name: 'HomeOutlined' }, onPress: onPressSpy })
fireEvent.press(screen.getByRole('button', { name: 'test' }))
expect(onPressSpy).toHaveBeenCalled()
})
Expand Down
7 changes: 4 additions & 3 deletions VAMobile/src/components/Templates/FullScreenSubtask.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'

import { VAIconProps } from 'components/VAIcon'
import { IconProps } from '@department-of-veterans-affairs/mobile-component-library/src/components/Icon/Icon'

import { context, fireEvent, render, screen } from 'testUtils'

import FullScreenSubtask from './FullScreenSubtask'
Expand All @@ -12,7 +13,7 @@ context('FullScreenSubtask', () => {
titleText?: string,
leftButtonText?: string,
rightButtonText?: string,
rightVAIconProps?: VAIconProps,
rightIconProps?: IconProps,
primaryContentButtonText?: string,
onPrimaryButtonPress?: () => void,
secondaryContentButtonText?: string,
Expand All @@ -23,7 +24,7 @@ context('FullScreenSubtask', () => {
title={titleText}
leftButtonText={leftButtonText}
rightButtonText={rightButtonText}
rightVAIconProps={rightVAIconProps}
rightVAIconProps={rightIconProps}
primaryContentButtonText={primaryContentButtonText}
onPrimaryContentButtonPress={onPrimaryButtonPress}
secondaryContentButtonText={secondaryContentButtonText}
Expand Down
4 changes: 2 additions & 2 deletions VAMobile/src/components/Templates/FullScreenSubtask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { StackActions, useNavigation } from '@react-navigation/native'

import { Button, ButtonVariants } from '@department-of-veterans-affairs/mobile-component-library'
import { IconProps } from '@department-of-veterans-affairs/mobile-component-library/src/components/Icon/Icon'

import { Box, CrisisLineButton, TextView, TextViewProps, VAScrollView, WaygateWrapper } from 'components'
import { MenuViewActionsType } from 'components/Menu'
import { VAIconProps } from 'components/VAIcon'
import { NAMESPACE } from 'constants/namespaces'
import { useDestructiveActionSheet, useTheme } from 'utils/hooks'

Expand Down Expand Up @@ -44,7 +44,7 @@ export type FullScreenSubtaskProps = {
/** Optional TestID for right button */
rightButtonTestID?: string
/** icon for title bar right button(must have right button text to display) */
rightVAIconProps?: VAIconProps
rightVAIconProps?: IconProps
/** ref for the VAScrollView component that contains the content */
scrollViewRef?: Ref<ScrollView>
/** shows the menu icon with the specified action types (won't be shown if right button text is set) */
Expand Down
9 changes: 5 additions & 4 deletions VAMobile/src/components/Templates/HeaderBanner.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'

import { VAIconProps } from 'components/VAIcon'
import { IconProps } from '@department-of-veterans-affairs/mobile-component-library/src/components/Icon/Icon'

import { context, fireEvent, render, screen } from 'testUtils'

import HeaderBanner, { HeaderLeftButtonProps, HeaderRightButtonProps, HeaderStaticTitleProps } from './HeaderBanner'
Expand All @@ -14,7 +15,7 @@ context('HeaderBanner', () => {
onLeftTitleButtonPress?: () => void,
rightButtonText?: string,
onRightTitleButtonPress?: () => void,
rightVAIconProps?: VAIconProps,
rightIconProps?: IconProps,
): void => {
let leftButton: HeaderLeftButtonProps | undefined
if (leftButtonText && onLeftTitleButtonPress) {
Expand All @@ -23,8 +24,8 @@ context('HeaderBanner', () => {
const title: HeaderStaticTitleProps | undefined = titleText ? { type: 'Static', title: titleText } : undefined
let rightButton: HeaderRightButtonProps | undefined
if (rightButtonText && onRightTitleButtonPress) {
if (rightVAIconProps) {
rightButton = { text: rightButtonText, onPress: onRightTitleButtonPress, icon: rightVAIconProps }
if (rightIconProps) {
rightButton = { text: rightButtonText, onPress: onRightTitleButtonPress, icon: rightIconProps }
} else {
rightButton = { text: rightButtonText, onPress: onRightTitleButtonPress }
}
Expand Down
8 changes: 5 additions & 3 deletions VAMobile/src/components/Templates/HeaderBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { Shadow, ShadowProps } from 'react-native-shadow-2'

import { useFocusEffect } from '@react-navigation/native'

import { Box, BoxProps, DescriptiveBackButton, TextView, TextViewProps, VAIconProps, VAIconWithText } from 'components'
import { IconProps } from '@department-of-veterans-affairs/mobile-component-library/src/components/Icon/Icon'

import { Box, BoxProps, DescriptiveBackButton, IconWithText, TextView, TextViewProps } from 'components'
import MenuView, { MenuViewActionsType } from 'components/Menu'
import colors from 'styles/themes/VAColors'
import { useAccessibilityFocus, useIsScreenReaderEnabled, useTheme } from 'utils/hooks'
Expand Down Expand Up @@ -45,7 +47,7 @@ export type HeaderRightButtonProps = {
a11yLabel?: string
accessibilityRole?: AccessibilityRole
onPress: () => void
icon?: VAIconProps
icon?: IconProps
testID?: string
}

Expand Down Expand Up @@ -315,7 +317,7 @@ const HeaderBanner: FC<HeaderBannerProps> = ({
accessibilityRole={rightButton.accessibilityRole || 'button'}>
<Box {...commonBoxProps}>
{rightButton.icon ? (
<VAIconWithText
<IconWithText
testID={rightButton.testID}
label={rightButton.text}
labelA11y={rightButton.a11yLabel}
Expand Down
2 changes: 1 addition & 1 deletion VAMobile/src/components/VAIcon/VAIcon.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jest.mock('../../utils/hooks', () => {
context('VAIconTests', () => {
describe('optional parameters', () => {
it('should get passed to svg component', () => {
render(<VAIcon name={'HomeSelected'} testID={'myId'} height={1} width={2} />)
render(<VAIcon name={'Chat'} testID={'myId'} height={1} width={2} />)

expect(screen.getByTestId('myId')).toBeTruthy()
})
Expand Down
Loading

0 comments on commit 1edd172

Please sign in to comment.