Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Mantine UI Series] Notification ( Systems) and Alert #24

Open
reboottime opened this issue Aug 8, 2023 · 3 comments
Open

[Mantine UI Series] Notification ( Systems) and Alert #24

reboottime opened this issue Aug 8, 2023 · 3 comments

Comments

@reboottime
Copy link
Owner

reboottime commented Aug 8, 2023

Overview

This article talks about

  • Mantine UI Notification System
  • and best practices I learned from reading its source code.
  • A small comparison between Alert and Notification component.

Notification Vs Alert

At UI and accessibility level, the Notification and Alert components exhibit a striking similarity. However, their usage differs in the following ways:

  • Alert is for attracting user attention with important static message
  • Notification is for showing dynamic notifications and alerts to user.
@reboottime
Copy link
Owner Author

reboottime commented Aug 8, 2023

Notification System and its Application

Mantine UI's notification system operates as a toast solution, simplifying the process of programmatically.


Mantine UI notification system comprises three primary parts:

  1. The Notifications component, which serves as both a container for programmatically added notifications and a functional element used in notifications.
  2. The Notification component, responsible for holding notification information.
  3. A collection of helper functions are exposed to developers, offering developers the capability to manage notifications programmatically. Below, is a tailored toast utils built upon Mantine Notification system.

const toast = {
    error: (message: string, options?: NotificationProps) => {
        notifications.show({
            ...options,
            color: 'red',
            icon: <IconX size="1.1rem" />,
            message,
            title: 'Error'
        });
    },
    success: (message: string, options: NotificationProps) => {
        notifications.show({
            ...options,
            color: 'green',
            icon: <IconCheck size="1.1rem" />,
            message,
            title: 'Success'
        });
    },
    info: (message: string, options?: NotificationProps) => {
        notifications.show({
            ...options,
            color: 'cyan',
            icon: <IconInfoCircle size="1.1rem" />,
            message,
            title: 'Info'
        });
    }
};

@reboottime
Copy link
Owner Author

reboottime commented Aug 8, 2023

Learnings from Mantine UI Notification System

The Animation Effect





Manage Notifications Programmatically


A general solution

  • Create a NotificationProvider that accepts value as bellow:
    • Notification management functions from useState
    • Notifications generated from useState
  • Expose the useNotifications hook for developers to access and manage notifications
  • Wrap the components/hooks where we might need access/manage notifications.

Bellow is the sample code:

export const NotificationProvider = ({children}) => {
   const [notifications, setNotifications] = useState([]);

   const value = useMemo({
     notifications,
     addNotification:  (notification) => setNotifications(prevNotifications => [prevNotifications, notification])
    }, [notifications]);

   return <NotificationProvider value={value}>{children}</NotificationProvider>
};

// How we use the Notification system

const App = () => {
  return <NotificationProvider>{/**some other code**/} </NotificationProvider>
};

While this approach is functional, the drawback are

  • Whenever there's a change in notification(s), it causes unnecessary rendering to its descendants.
  • The above solution can't help when we want to toast a notification outside of React hooks or components, for example, toast a notification at the Axios response interceptor function whenever backend gives us 403 HTTP status.

The Novel Solution ( by Mantine UI)

  1. How Mantine Notifications System manages notifications limit in a timeframe.

Mantine UI notification system relies on use-queue to limit what notifications are should be rendered, and what notifications are waiting in the notification system's queue

const { state, queue, update, cleanQueue } = useQueue<NotificationProps>({
  initialValues: [],
  limit,
});
  1. How Mantine UI exposes its notification management helpers

Mantine Notification System employs window as the cross components communication channel for notifications management. Here are how it works under the hood

  • Define Notification State: The notifications' state and its management functions are established within the Notifications component using use-notification-state.
  • Expose Management Functions: The management functions for notification state are made available through useNotificationsEvents, generated by invoking createUseExternalEvents.
  • Custom DOM Events: Internally, createUseExternalEvents registers custom DOM events at the window level. These events are activated whenever any notification management function is called.
  • State Manipulation: Triggering a notification management function effectively corresponds to activating a corresponding window event, which in turn manipulates the notifications' state.

Following are some key source code screenshot

  • Declare state and state management functions

image
  • Attach the state management functions to window event dispatcher and creator

image
image
image

@reboottime
Copy link
Owner Author

reboottime commented Aug 8, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant