Skip to content

Commit

Permalink
Implement IconBadge
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon-edge committed Nov 1, 2024
1 parent 1f0b6f7 commit e30ca57
Showing 1 changed file with 102 additions and 0 deletions.
102 changes: 102 additions & 0 deletions src/components/icons/IconBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import * as React from 'react'
import { Platform, StyleProp, View, ViewStyle } from 'react-native'

import { EdgeTouchableOpacity } from '../common/EdgeTouchableOpacity'
import { cacheStyles, Theme, useTheme } from '../services/ThemeContext'
import { EdgeText } from '../themed/EdgeText'

const SCALE = 0.9

export interface Props {
children: React.ReactNode
sizeRem: number
onPress: () => void | Promise<void>
/**
* - If undefined, renders nothing.
* - If 0, renders a red dot with a white circle inside.
* - All other cases: renders a red dot with the number inside in white
*/
number?: number
testID?: string
}

/**
* Maybe renders a red dot badge on top of the supplied `children,` with a white
* number or dot inside. Visibility of the red dot depends on the `number` prop.
*/
export const IconBadge = (props: Props) => {
const { number, children, sizeRem, testID, onPress } = props
const theme = useTheme()
const styles = getStyles(theme)

const size = theme.rem(sizeRem)
const containerStyle: StyleProp<ViewStyle> = React.useMemo(
() => ({
// ...styles.tappableArea,
height: size,
width: size,
alignItems: 'center',
justifyContent: 'center'
}),
[size]
)

return (
<EdgeTouchableOpacity accessible={false} style={containerStyle} onPress={onPress} testID={testID}>
{children}
{number == null ? null : (
<View style={styles.badgeContainer}>
{number === 0 ? (
<View style={styles.circle} />
) : (
<EdgeText style={[styles.superscriptLabel, Platform.OS === 'android' ? styles.androidAdjust : null]} disableFontScaling>
{number}
</EdgeText>
)}
</View>
)}
</EdgeTouchableOpacity>
)
}

const getStyles = cacheStyles((theme: Theme) => {
const badgeSize = theme.rem(0.75) * SCALE

return {
iconContainer: {
alignItems: 'center',
justifyContent: 'center'
},
badgeContainer: {
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
top: 0,
right: 0,
height: badgeSize,
minWidth: badgeSize,
borderRadius: badgeSize / 2,
paddingLeft: theme.rem(0.25) / 2,
paddingRight: theme.rem(0.25) / 2,
backgroundColor: 'red'
},
label: {
textAlign: 'center',
marginBottom: theme.rem(0.5)
},
superscriptLabel: {
fontSize: theme.rem(0.5)
},
androidAdjust: {
marginTop: 2,
marginLeft: 1
},
circle: {
width: theme.rem(0.25),
height: theme.rem(0.25),
borderRadius: theme.rem(0.125),
backgroundColor: 'white',
alignSelf: 'center'
}
}
})

0 comments on commit e30ca57

Please sign in to comment.