Tag
Tags provide quick contextual keywords to inform status of a row or item.
Examples
Default
Variations
Usage
When to use Tags
- When there is a list of information with different statuses for different items
How this component works
- Only one tag should be used per instance.
- The trailing icon is optional, as the status definition will not apply in all use cases. When the icon is used, the tag becomes a tappable button and opens a full panel.
Choosing between variations
- Static vs Interactive
- Static: To indicate a status that does not need further explanation or definition
- Interactive: When you need to provide additional context for a status, use the interactive version with the icon.
- Status
- Informative (blue): To indicate neutral, default content. Consider the Informative status for new content with expected changes in status and trailing actions to take, like an Active prescription.
- Success (green): To indicate completed, finalized content. Consider the Success status for content with no further outstanding tasks, like a Confirmed appointment, or an In-Progress prescription refill.
- Indeterminate/Unresolved (yellow): To indicate pending actions or content that is still in-progress. Consider the Indeterminate status for content either the system or user can resolve, like a Pending appointment, or an On-Hold prescription refill.
- Inactive (gray): To indicate content that has no further actions. Consider the Inactive status for "dead ends", such as a Read message, a Canceled appointment, or an Expired prescription.
Instances of this component in production
- In Prescription cards
- In Appointment cards
Content considerations
- Use common VA language, words, or terms for copy.
- Keep copy to as few words as possible (1-2 words). There are exceptions where 3 or 4 words must be used in cases of VA-specific phrases or words.
- The trailing info icon is optional. Not all tags will need one for further definition of the copy.
- Use sentence case (i.e., Sentence case, not Title Case). Exceptions include words/phrases that use Title Case in other VA tools/sites.
- The trailing icon should clearly describe the type of content that it will display. For example, use the info icon when additional information will display on tap.
Accessibility considerations
- If user has magnification settings, the trailing info-icon should scale along with the font.
- The icon is decorative, so it does not need to be read by a screen reader. If the icon is included, the tag should be read as a button.
Related
Code usage
Common component to show a text inside a tag- Properties
- Example
- Source Code
- Accessibility
Name | Type | Default Value | Required | Description |
---|---|---|---|---|
text | string | Yes | Message to be shown on the tag | |
labelType | LabelTagTypes | Yes | Defines the color and look of the tag | |
a11yLabel | string | No | Optional accessibility label | |
onPress | () => void | No | Optional method called when tag is pressed | |
a11yHint | string | No | Optional accessibility hint if there is an on press | |
a11yRole | AccessibilityRole | No | Optional role to override the default role of button |
How to use the LabelTag component
<LabelTag text={'value'} />
Full code for the LabelTag component
import React, { FC } from 'react'
import { AccessibilityRole, Pressable, PressableProps, useWindowDimensions } from 'react-native'
import { Icon, IconProps } from '@department-of-veterans-affairs/mobile-component-library'
import { useTheme } from 'utils/hooks'
import Box, { BoxProps } from './Box'
import TextView from './TextView'
export const LabelTagTypeConstants: {
tagBlue: LabelTagTypes
tagInactive: LabelTagTypes
tagYellow: LabelTagTypes
tagGreen: LabelTagTypes
} = {
tagBlue: 'tagBlue',
tagInactive: 'tagInactive',
tagYellow: 'tagYellow',
tagGreen: 'tagGreen',
}
export type LabelTagTypes = 'tagBlue' | 'tagInactive' | 'tagYellow' | 'tagGreen'
export type LabelTagProps = {
/** Message to be shown on the tag*/
text: string
/** Defines the color and look of the tag */
labelType: LabelTagTypes
/** Optional accessibility label */
a11yLabel?: string
/** Optional method called when tag is pressed */
onPress?: () => void
/** Optional accessibility hint if there is an on press */
a11yHint?: string
/** Optional role to override the default role of button */
a11yRole?: AccessibilityRole
}
/**Common component to show a text inside a tag*/
const LabelTag: FC<LabelTagProps> = ({ text, labelType, onPress, a11yHint, a11yLabel, a11yRole }) => {
const theme = useTheme()
const fontScale = useWindowDimensions().fontScale
const adjustSize = fontScale >= 2
const textView = (
<TextView
flexWrap={'wrap'}
color={'labelTag'}
variant={'LabelTag'}
pl={adjustSize ? 30 : 12}
pr={adjustSize ? 8 : 12}
pt={adjustSize ? 8 : 4}
pb={adjustSize ? 12 : 4}>
{text}
</TextView>
)
let wrapperProps: BoxProps = {
minWidth: theme.dimensions.tagMinWidth,
minHeight: theme.dimensions.touchableMinHeight,
justifyContent: 'center',
alignSelf: 'flex-start',
alignItems: 'center',
flexDirection: 'row',
backgroundColor: labelType,
borderColor: labelType,
borderWidth: 1,
borderRadius: 100,
}
const getContent = () => {
if (!onPress) {
if (a11yLabel) {
wrapperProps = {
...wrapperProps,
accessibilityLabel: a11yLabel,
}
}
return <Box {...wrapperProps}>{textView}</Box>
}
let pressableProps: PressableProps = {
onPress: onPress,
accessible: true,
accessibilityRole: a11yRole || 'button',
}
if (a11yHint) {
pressableProps = {
...pressableProps,
accessibilityHint: a11yHint,
}
}
if (a11yLabel) {
pressableProps = {
...pressableProps,
accessibilityLabel: a11yLabel,
}
}
const infoIconProps: IconProps = {
name: 'Info',
fill: theme.colors.icon.tagInfoIcon,
height: adjustSize ? 13 : 20,
width: adjustSize ? 13 : 20,
}
return (
<Pressable {...pressableProps}>
<Box {...wrapperProps}>
{textView}
<Box mr={adjustSize ? 5 : 10}>
<Icon {...infoIconProps} />
</Box>
</Box>
</Pressable>
)
}
return getContent()
}
export default LabelTag