Skip to content
This repository was archived by the owner on Mar 25, 2025. It is now read-only.

Commit 37ad7cc

Browse files
danielkaxisTigge
authored andcommitted
feat(toast): use toasts from context
Enables use of different ToastAnchors throughout the application sharing the toasts.
1 parent a35215a commit 37ad7cc

File tree

5 files changed

+41
-43
lines changed

5 files changed

+41
-43
lines changed

packages/core/src/Toast/ToastsProvider.tsx

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {
33
useContext,
44
useRef,
55
FC,
6-
Dispatch,
76
isValidElement,
87
cloneElement,
98
ReactNode,
@@ -18,7 +17,7 @@ import { BaseToast } from './Toast'
1817
import { toastReducer } from './toastReducer'
1918

2019
import { useToastCallbacks, SimpleToastsDurations } from './useToasts'
21-
import { ToastAction, NI, ToastsContext } from './context'
20+
import { ToastsContext } from './context'
2221

2322
export interface ToastsPlacement {
2423
readonly justify: 'center' | 'right'
@@ -65,12 +64,12 @@ export const ToastsProvider: FC<ToastsProviderProps> = ({
6564
children,
6665
...toastsOptions
6766
}) => {
68-
const __dispatchRef = useRef<Dispatch<ToastAction>>(NI)
67+
const [toasts, dispatch] = useReducer(toastReducer, new Map())
6968

70-
const callbacks = useToastCallbacks(__dispatchRef, toastsOptions)
69+
const callbacks = useToastCallbacks(dispatch, toastsOptions)
7170

7271
return (
73-
<ToastsContext.Provider value={{ ...callbacks, __dispatchRef }}>
72+
<ToastsContext.Provider value={{ ...callbacks, dispatch, toasts }}>
7473
{children}
7574
</ToastsContext.Provider>
7675
)
@@ -109,25 +108,28 @@ export interface ToastsAnchorProps {
109108
}
110109

111110
export const ToastsAnchor: FC<ToastsAnchorProps> = ({ placement }) => {
112-
const [toasts, dispatch] = useReducer(toastReducer, new Map())
113-
const { hideToast, __dispatchRef } = useContext(ToastsContext)
114-
__dispatchRef.current = dispatch
115-
116111
return (
117112
<ToastsWrapper {...placement}>
118-
<TransitionGroup component={null}>
119-
{[...toasts.entries()].map(([id, props], index) => (
120-
<ToastTransition key={id}>
121-
<BaseToast
122-
key={id}
123-
toastId={id}
124-
zIndex={-index}
125-
dismissToast={hideToast}
126-
{...props}
127-
/>
128-
</ToastTransition>
129-
))}
130-
</TransitionGroup>
113+
<ToastContent />
131114
</ToastsWrapper>
132115
)
133116
}
117+
118+
export const ToastContent = () => {
119+
const { hideToast, toasts } = useContext(ToastsContext)
120+
return (
121+
<TransitionGroup component={null}>
122+
{[...toasts.entries()].map(([id, props], index) => (
123+
<ToastTransition key={id}>
124+
<BaseToast
125+
key={id}
126+
toastId={id}
127+
zIndex={-index}
128+
dismissToast={hideToast}
129+
{...props}
130+
/>
131+
</ToastTransition>
132+
))}
133+
</TransitionGroup>
134+
)
135+
}

packages/core/src/Toast/context.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createContext, ReactNode, MutableRefObject, Dispatch } from 'react'
1+
import { createContext, ReactNode, Dispatch } from 'react'
22
import { IconType } from '../Icon'
33
import { ALinkProps, ButtonLinkProps } from '../Link'
44

@@ -25,6 +25,8 @@ export interface ProgressToast extends SimpleToast {
2525
}
2626
}
2727

28+
export type ToastsMap = ReadonlyMap<ToastId, BaseToastValue>
29+
2830
export type ShowToastHandler = (toast: BaseToastValue, id?: ToastId) => ToastId
2931
export type HideToastHandler = (id: ToastId) => void
3032
export type SimpleToastCreator = (toast: SimpleToast, id?: ToastId) => ToastId
@@ -88,7 +90,8 @@ export const NI = () => {
8890
throw new Error(`Not implemented: no ToastContext set`)
8991
}
9092
export interface ToastContextType extends ToastCallbacks {
91-
readonly __dispatchRef: MutableRefObject<Dispatch<ToastAction>>
93+
readonly dispatch: Dispatch<ToastAction>
94+
readonly toasts: ToastsMap
9295
}
9396

9497
export const ToastsContext = createContext<ToastContextType>({
@@ -102,5 +105,6 @@ export const ToastsContext = createContext<ToastContextType>({
102105
showLoadingToast: NI,
103106
showProgressToast: NI,
104107
showActionToast: NI,
105-
__dispatchRef: { current: NI },
108+
dispatch: NI,
109+
toasts: new Map(),
106110
})

packages/core/src/Toast/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ export {
77
ToastIconWrapper,
88
ToastIconType,
99
} from './toastCreators'
10+
export { ToastContent } from './ToastsProvider'

packages/core/src/Toast/toastReducer.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
import {
2-
BaseToastValue,
3-
ToastAction,
4-
ToastActionType,
5-
ToastId,
6-
} from './context'
7-
8-
export type ToastsMap = ReadonlyMap<ToastId, BaseToastValue>
1+
import { ToastAction, ToastActionType, ToastsMap } from './context'
92

103
/**
114
* Given the current state (toast map) and an action,

packages/core/src/Toast/useToasts.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { MutableRefObject, Dispatch, useContext, useCallback } from 'react'
1+
import { Dispatch, useContext, useCallback } from 'react'
22

33
import { createToast, removeToast, removeAllToasts } from './toastActions'
44
import {
@@ -30,29 +30,27 @@ export interface SimpleToastsDurations {
3030
}
3131

3232
export const useToastCallbacks = (
33-
dispatchRef: MutableRefObject<Dispatch<ToastAction>>,
33+
dispatch: Dispatch<ToastAction>,
3434
{ success, error, warning, info }: SimpleToastsDurations = {}
3535
): ToastCallbacks => {
3636
const showToast: ShowToastHandler = useCallback(
3737
(toast, id) => {
3838
const toastAction = createToast(toast, id)
39-
dispatchRef.current(toastAction)
39+
dispatch(toastAction)
4040
return toastAction.id
4141
},
42-
[dispatchRef]
42+
[dispatch]
4343
)
4444

4545
const hideToast: HideToastHandler = useCallback(
4646
id => {
4747
const toastAction = removeToast(id)
48-
dispatchRef.current(toastAction)
48+
dispatch(toastAction)
4949
},
50-
[dispatchRef]
50+
[dispatch]
5151
)
5252

53-
const clearToasts = useCallback(() => {
54-
dispatchRef.current(removeAllToasts)
55-
}, [dispatchRef])
53+
const clearToasts = useCallback(() => dispatch(removeAllToasts), [dispatch])
5654

5755
const showSuccessToast: SimpleToastCreator = useCallback(
5856
(toast, id) =>
@@ -111,7 +109,7 @@ export const useToastCallbacks = (
111109
}
112110

113111
export const useToasts = () => {
114-
const { __dispatchRef, ...callbacks } = useContext(ToastsContext)
112+
const { dispatch, toasts, ...callbacks } = useContext(ToastsContext)
115113

116114
return callbacks
117115
}

0 commit comments

Comments
 (0)