-
-
Notifications
You must be signed in to change notification settings - Fork 300
/
MessageQueue.tsx
81 lines (76 loc) · 2.5 KB
/
MessageQueue.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import type { ReactElement, ReactNode } from "react";
import { useMemo } from "react";
import type { AddMessage, Message, ToastMessage } from "./MessageQueueContext";
import {
AddMessageContext,
MessageQueueActionsContext,
MessageQueueContext,
MessageVisibilityContext,
} from "./MessageQueueContext";
import type { SnackbarProps } from "./Snackbar";
import type { ActionEventHandler } from "./SnackbarQueue";
import { SnackbarQueue } from "./SnackbarQueue";
import type { MessageQueueOptions } from "./useMessageQueue";
import { useMessageQueue } from "./useMessageQueue";
export interface MessageQueueProps<M extends ToastMessage>
extends MessageQueueOptions<M>,
SnackbarProps {
/**
* The children are required in this component since the message queue relies
* on setting up React Context and provide hooks to add a message to the
* queue. If there are no children, the message queue will not work.
*/
children: ReactNode;
/**
* An optional function to call when the action button is clicked. This will
* be applied to **all** toasts that appear in this message queue. You will
* be provided the current message followed by the click event.
*/
onActionClick?: ActionEventHandler<M>;
}
/**
* This component is used to be able to create a queue of messages with the
* `Snackbar` and `Toast` components with a _fairly_ decent API out of the box.
*/
export function MessageQueue<M extends ToastMessage = ToastMessage>({
timeout = 5000,
duplicates = "allow",
defaultQueue = [],
children,
...props
}: MessageQueueProps<M>): ReactElement {
const {
queue,
visible,
hideMessage,
startTimer,
stopTimer,
restartTimer,
addMessage,
popMessage,
resetQueue,
} = useMessageQueue<M>({ timeout, duplicates, defaultQueue });
const actions = useMemo(
() => ({
popMessage,
hideMessage,
startTimer,
stopTimer,
resetQueue,
restartTimer,
}),
[popMessage, hideMessage, startTimer, stopTimer, restartTimer, resetQueue]
);
return (
<AddMessageContext.Provider value={addMessage as AddMessage<Message>}>
<MessageQueueActionsContext.Provider value={actions}>
<MessageVisibilityContext.Provider value={visible}>
<MessageQueueContext.Provider value={queue}>
{children}
</MessageQueueContext.Provider>
<SnackbarQueue {...props} queue={queue} />
</MessageVisibilityContext.Provider>
</MessageQueueActionsContext.Provider>
</AddMessageContext.Provider>
);
}