Skip to content

Commit

Permalink
fix: remove Partial type annotation and provide default value for `to…
Browse files Browse the repository at this point in the history
…ast` to avoid null checking

fix: add SafeAreaView for correct offset values

feat: add accentColor prop to ToastConfig

feat: add `INFO` intent and update handling

fix: update styles to allow correct wrapping of text

fix: use reference of animated value to avoid values getting reset
  • Loading branch information
Jean Verster committed Oct 6, 2020
1 parent 41b1357 commit 99f9cb3
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 41 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
},
"dependencies": {
"@types/styled-components": "^5.1.1",
"react-native-safe-area-context": "^3.1.8",
"react-native-status-bar-height": "^2.5.0"
},
"release": {
Expand Down
19 changes: 12 additions & 7 deletions src/Context/index.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
import * as React from 'react'
import { LayoutAnimation, UIManager } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import { getStatusBarHeight } from 'react-native-status-bar-height'
import Box from '../Box'
import Toast, { ToastConfig } from '../Toast'
import { ToastInternalConfig } from '../Toast/index'
import { uuid } from '../Utils'

type ToastContextType = {
toast?: (options: ToastConfig) => void
toast: (options: ToastConfig) => void
position?: 'TOP' | 'BOTTOM'
offset?: number
}

export const ToastContext = React.createContext<Partial<ToastContextType>>({})
export const ToastContext = React.createContext<ToastContextType>({
toast: () => null
})

export const useToast = () => React.useContext(ToastContext)

const originalOffset = getStatusBarHeight(true) + 16
const originalOffset = getStatusBarHeight() + 16

UIManager && UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true)

export type FullToastConfig = ToastConfig & ToastInternalConfig

const ToastProvider: React.FC<ToastContextType> = ({ children, position, offset: offsetProp }) => {
const ToastProvider: React.FC<Omit<ToastContextType, 'toast'>> = ({ children, position, offset: offsetProp }) => {
const [toasts, setToasts] = React.useState<FullToastConfig[]>([])

const toast = (newToast: ToastConfig) => {
Expand Down Expand Up @@ -54,9 +57,11 @@ const ToastProvider: React.FC<ToastContextType> = ({ children, position, offset:
pb={position === 'BOTTOM' ? offset : 0}
style={position === 'BOTTOM' ? { bottom: 0 } : { top: 0 }}
>
{toasts.map((config: ToastConfig & ToastInternalConfig) => {
return <Toast position={position} key={config.id} onClose={(id) => hideToast(id)} {...config} />
})}
<SafeAreaView style={{ flex: 1, justifyContent: 'flex-start' }}>
{toasts.map((config: ToastConfig & ToastInternalConfig) => {
return <Toast position={position} key={config.id} onClose={(id) => hideToast(id)} {...config} />
})}
</SafeAreaView>
</Box>
</ToastContext.Provider>
)
Expand Down
57 changes: 30 additions & 27 deletions src/Toast/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import * as React from 'react'
import { Animated, StyleSheet, TouchableOpacity, Vibration } from 'react-native'
import { Animated, Vibration } from 'react-native'
import { getStatusBarHeight } from 'react-native-status-bar-height'
import Box from '../Box'
import Icon from '../Icon'
import { Accent, CloseButtonCont, Heading, IconCont, StyledToast, SubText } from './styles'

export type ToastConfig = {
accentColor?: string
bg?: string
borderColor?: string
closeButtonBgColor?: string
Expand Down Expand Up @@ -35,7 +36,7 @@ export type ToastConfig = {
iconColor?: string
}

const statusBarHeight = getStatusBarHeight(true)
const statusBarHeight = getStatusBarHeight()

export type ToastInternalConfig = {
id?: string
Expand All @@ -58,6 +59,7 @@ const shadow = {
}

export const Toast: React.FC<ToastConfig & ToastInternalConfig> = ({
accentColor,
bg,
borderColor,
closeButtonBgColor,
Expand All @@ -80,9 +82,10 @@ export const Toast: React.FC<ToastConfig & ToastInternalConfig> = ({
iconColor
}) => {
const isSuccess = intent === 'SUCCESS'
const isInfo = intent === 'INFO'
const topOffset = offset + 60 * (index || 0)

const animation = new Animated.Value(0)
const animation = React.useRef(new Animated.Value(0)).current

React.useEffect(() => {
Animated.timing(animation, {
Expand Down Expand Up @@ -120,35 +123,35 @@ export const Toast: React.FC<ToastConfig & ToastInternalConfig> = ({
mb={4}
py={2}
bg={bg}
onPress={onPress}
pr={!!subMessage ? 2 : 0}
borderColor={borderColor}
style={{ transform: [{ translateY }, { scale }], ...shadow }}
>
<TouchableOpacity
activeOpacity={1}
onPress={onPress}
testID="toast-touchable"
style={{ ...StyleSheet.absoluteFillObject, flexDirection: 'row' }}
>
<Accent testID="toast-accent" bg={isSuccess ? 'success' : 'error'} />
{!hideIcon && (
<IconCont px={4}>
<Icon
size={20}
family={iconFamily || 'Feather'}
color={!!iconColor ? iconColor : isSuccess ? 'success' : 'error'}
name={!!iconName ? iconName : isSuccess ? 'check-circle' : 'x-circle'}
/>
</IconCont>
)}
<Box pl={hideIcon ? 4 : 0} flex={1} alignItems="flex-start">
<Accent
testID="toast-accent"
bg={!!accentColor ? accentColor : isSuccess ? 'success' : isInfo ? 'info' : 'error'}
/>
{!hideIcon && (
<IconCont px={4}>
<Icon
size={20}
family={iconFamily || 'Feather'}
color={!!iconColor ? iconColor : isSuccess ? 'success' : isInfo ? 'info' : 'error'}
name={!!iconName ? iconName : isSuccess ? 'check-circle' : isInfo ? 'alert-circle' : 'x-circle'}
/>
</IconCont>
)}
<Box py={2} pr={!!subMessage ? 2 : 0} flex={1} pl={hideIcon ? 4 : 0} alignItems="flex-start">
<Box flexDirection="row" flexWrap="wrap" flex={1}>
<Heading color={color}>{message}</Heading>
{!!subMessage && (
<SubText color={color} mt={2}>
{subMessage}
</SubText>
)}
</Box>
</TouchableOpacity>
{!!subMessage && (
<SubText color={color} mt={1}>
{subMessage}
</SubText>
)}
</Box>
<CloseButtonCont onPress={() => onClose && id && onClose(id)}>
<Box p={2} mx={2} alignItems="center" bg={closeButtonBgColor} borderRadius={closeButtonBorderRadius}>
<Icon size={20} family="Feather" name="x" color={closeIconColor} />
Expand Down
12 changes: 5 additions & 7 deletions src/Toast/styles.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Animated } from 'react-native'
import { Animated, TouchableOpacity } from 'react-native'
import styled from 'styled-components/native'
import {
borderColor,
Expand All @@ -22,15 +22,17 @@ type StyledToastProps = SpaceProps &
accentColor?: string
}

export const StyledToast = styled(Animated.View)<StyledToastProps>`
const AnimatedTouchable = Animated.createAnimatedComponent(TouchableOpacity)

export const StyledToast = styled(AnimatedTouchable)<StyledToastProps>`
${top};
${color};
${space};
${borderColor};
flex: 1;
width: 100%;
z-index: 1000;
border-width: 1px;
min-height: 50px;
border-radius: 4px;
align-items: center;
flex-direction: row;
Expand Down Expand Up @@ -91,10 +93,6 @@ export const IconCont = styled.View<SpaceProps>`

export const CloseButtonCont = styled.TouchableOpacity<SpaceProps>`
${space};
top: 0;
right: 0;
bottom: 0;
position: absolute;
align-items: center;
justify-content: center;
`
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6388,6 +6388,11 @@ react-is@^16.8.1, react-is@^16.8.3, react-is@^16.8.4:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.11.0.tgz#b85dfecd48ad1ce469ff558a882ca8e8313928fa"
integrity sha512-gbBVYR2p8mnriqAwWx9LbuUrShnAuSCNnuPGyc7GJrMVQtPDAh8iLpv7FRuMPFb56KkaVZIYSz1PrjI9q0QPCw==

react-native-safe-area-context@^3.1.8:
version "3.1.8"
resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-3.1.8.tgz#7a9883aa0f38f9c77d4bef2b89e4e285bc1024a3"
integrity sha512-9gUlsDZ96QwT9AKzA6aVWM/NX5rlJgauZ9HgCDVzKbe29UQYT1740QJnnaI2GExmkFGp6o7ZLNhCXZW95eYVFA==

react-native-status-bar-height@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/react-native-status-bar-height/-/react-native-status-bar-height-2.5.0.tgz#bc0fb85230603850aab9667ee8111a62954de90c"
Expand Down

0 comments on commit 99f9cb3

Please # to comment.