PluginProbe
Vimeography: Vimeo Video Gallery WordPress Plugin / 2.2
Vimeography: Vimeo Video Gallery WordPress Plugin v2.2
2.4.9 2.4.8 trunk 0.5.1 0.5.2 0.5.3 0.5.4 0.5.5 0.5.6 0.5.7 0.6 0.6.1 0.6.2 0.6.3 0.6.4 0.6.5 0.6.6 0.6.7 0.6.8 0.6.8.1 0.6.9 0.6.9.1 0.6.9.2 0.7 0.8 All 103 releases
vimeography / lib / admin / app / src / providers / Notification.tsx

Notification.tsx in Vimeography: Vimeo Video Gallery WordPress Plugin 2.2, at lib/admin/app/src/providers/Notification.tsx

101 lines 2.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import * as React from "react";
2 import * as ReactDOM from "react-dom";
3 import { motion } from "framer-motion";
4 import { nanoid } from "nanoid";
5
6 import NotificationContext from "../context/Notification";
7
8 type Notification = {
9 message: string;
10 type: "success" | "error";
11 };
12
13 const CLASSES = {
14 success: "vm-text-green-500",
15 error: "vm-text-red-600",
16 };
17
18 const variants = {
19 hidden: {
20 y: 200,
21 opacity: 0,
22 },
23 visible: {
24 y: 0,
25 opacity: 1,
26 },
27 };
28
29 const NotificationContainer = (props) => {
30 const notifications = props.notifications;
31
32 return ReactDOM.createPortal(
33 <div className="vm-absolute vm-bottom-5 vm-w-full vm-z-10 vm-flex vm-flex-col vm-items-center vm-justify-center">
34 {notifications.map((n) => (
35 <motion.div
36 key={n.id}
37 variants={variants}
38 initial="hidden"
39 animate="visible"
40 onClick={() => props.removeNotification(n.id)}
41 className={`vm-bg-white vm-shadow-xl vm-p-4 vm-rounded vm-mb-3 vm-border vm-border-solid vm-border-gray-100 vm-font-semibold ${
42 CLASSES[n.type]
43 }`}
44 >
45 {n.message}
46 </motion.div>
47 ))}
48 </div>,
49 document.body
50 );
51 };
52
53 const NotificationProvider = ({ children }) => {
54 const [notifications, setNotifications] = React.useState([]);
55
56 const showNotification = React.useCallback(
57 (type, message) => {
58 setNotifications((notifications) => [
59 ...notifications,
60 { id: nanoid(), message, type },
61 ]);
62 },
63 [setNotifications]
64 );
65
66 const removeNotification = React.useCallback(
67 (id) => {
68 setNotifications((notifications) =>
69 notifications.filter((t) => t.id !== id)
70 );
71 },
72 [setNotifications]
73 );
74
75 React.useEffect(() => {
76 const timers = notifications.map((n) => {
77 return setTimeout(() => {
78 removeNotification(n.id);
79 }, 3000);
80 });
81
82 return () => {
83 timers.map((timer) => clearTimeout(timer));
84 };
85 }, [notifications, removeNotification]);
86
87 return (
88 <NotificationContext.Provider
89 value={{ showNotification, removeNotification }}
90 >
91 <NotificationContainer
92 notifications={notifications}
93 removeNotification={removeNotification}
94 />
95 {children}
96 </NotificationContext.Provider>
97 );
98 };
99
100 export default NotificationProvider;
101