diff --git a/src/components/ui/Notification/Notification.tsx b/src/components/ui/Notification/Notification.tsx deleted file mode 100644 index dc517518..00000000 --- a/src/components/ui/Notification/Notification.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import { Button, Space, notification, theme } from "antd"; -import { Icon } from "../Icon"; -import { NotificationProps, NotificationApi } from "./Notification.types"; - -export const useNotification = (): NotificationApi => { - const { - token: { colorError, colorInfo, colorSuccess, colorWarning }, - } = theme.useToken(); - - const open = (props: NotificationProps) => { - const { - type = "info", - title, - message, - buttons = [], - duration = 4.5, - onClose, - onButtonClick, - } = props; - - const onButtonClickHandler = (payload: any) => { - onButtonClick?.(payload); - notification.destroy(); - }; - - const buttonsComponent = buttons.length > 0 && ( - - {buttons.map((button) => { - return ( - - ); - })} - - ); - - notification[type]({ - message: title || "Notification", - description: message, - duration, - style: { - borderLeft: `8px solid ${ - type === "success" - ? colorSuccess - : type === "error" - ? colorError - : type === "warning" - ? colorWarning - : colorInfo - }`, - }, - btn: buttonsComponent, - onClose, - }); - }; - - return { - open, - destroy: notification.destroy, - }; -}; diff --git a/src/components/ui/Notification/NotificationProvider.tsx b/src/components/ui/Notification/NotificationProvider.tsx new file mode 100644 index 00000000..6b902fa9 --- /dev/null +++ b/src/components/ui/Notification/NotificationProvider.tsx @@ -0,0 +1,133 @@ +/* eslint-disable react/prop-types */ +import React, { + createContext, + useContext, + ReactNode, + useMemo, + useCallback, +} from "react"; +import { Button, Space, notification, theme } from "antd"; +import { Icon } from "../Icon"; +import { + NotificationApi, + NotificationProps, + NotificationButton, +} from "./Notification.types"; + +interface NotificationContextType { + notificationApi: NotificationApi; +} + +const NotificationContext = createContext( + undefined, +); + +interface NotificationProviderProps { + children: ReactNode; +} + +export const NotificationProvider: React.FC = ({ + children, +}) => { + const { + token: { colorError, colorInfo, colorSuccess, colorWarning }, + } = theme.useToken(); + + const [api, contextHolder] = notification.useNotification({ + stack: { + threshold: 1, + }, + }); + + const open = useCallback( + (props: NotificationProps) => { + const { + type = "info", + title, + message, + buttons = [], + duration = 4.5, + onClose, + onButtonClick, + } = props; + + const onButtonClickHandler = (payload: any) => { + onButtonClick?.(payload); + api.destroy(); + }; + + const buttonsComponent = buttons.length > 0 && ( + + {buttons.map((button: NotificationButton) => { + return ( + + ); + })} + + ); + + (api as any)[type]({ + message: title || "Notification", + description: message, + duration, + style: { + borderLeft: `8px solid ${ + type === "success" + ? colorSuccess + : type === "error" + ? colorError + : type === "warning" + ? colorWarning + : colorInfo + }`, + }, + btn: buttonsComponent, + onClose, + showProgress: true, + pauseOnHover: true, + }); + }, + [api, colorError, colorInfo, colorSuccess, colorWarning], + ); + + const notificationApi: NotificationApi = useMemo( + () => ({ + open, + destroy: api.destroy, + }), + [open, api.destroy], + ); + + const contextValue = useMemo( + () => ({ + notificationApi, + }), + [notificationApi], + ); + + return ( + + {contextHolder} + {children} + + ); +}; + +export const useNotificationContext = (): NotificationApi => { + const context = useContext(NotificationContext); + if (!context) { + throw new Error( + "useNotificationContext must be used within a NotificationProvider", + ); + } + return context.notificationApi; +}; diff --git a/src/components/ui/Notification/index.ts b/src/components/ui/Notification/index.ts index 08d34bd4..0001b18b 100644 --- a/src/components/ui/Notification/index.ts +++ b/src/components/ui/Notification/index.ts @@ -1,4 +1,4 @@ -export * from "./Notification"; +export * from "./NotificationProvider"; export type { NotificationType, NotificationButton,