Skip to content

Instantly share code, notes, and snippets.

@robsonkades
Created August 16, 2022 19:12
Show Gist options
  • Save robsonkades/96e742f7ce41b7f7b11d58b58c954378 to your computer and use it in GitHub Desktop.
Save robsonkades/96e742f7ce41b7f7b11d58b58c954378 to your computer and use it in GitHub Desktop.
import type { OptionsObject, SnackbarKey, SnackbarMessage } from 'notistack';
interface Notification {
message: SnackbarMessage;
options: OptionsObject;
dismissed: boolean;
}
type Actions = {
push: (notification: Partial<Notification>) => SnackbarKey;
close: (key: SnackbarKey, dismissAll?: boolean) => void;
remove: (key: SnackbarKey) => void;
};
export type { Notification, Actions };
import { useCallback, useMemo } from 'react';
import { atom, useRecoilState } from 'recoil';
import type { SnackbarKey } from 'notistack';
import { notifications as notificationsDefaults } from '@/config';
import { Actions, Notification } from './types';
const notificationsState = atom<Notification[]>({
key: 'notificationsState',
default: [],
});
function useNotifications(): [Notification[], Actions] {
const [notifications, setNotifications] = useRecoilState(notificationsState);
const push = useCallback(
(notification: Partial<Notification>) => {
// TODO (Suren): use uuid
const id = Math.random().toString();
setNotifications((notifications): Notification[] => [
// TODO (Suren): use immer
...notifications,
{
...notification,
message: notification.message,
dismissed: false,
options: {
...notificationsDefaults.options,
...notification.options,
key: id,
},
},
]);
return id;
},
[setNotifications],
);
const close = useCallback(
(key: SnackbarKey, dismissAll = !key) => {
setNotifications((notifications) =>
notifications.map((notification) =>
dismissAll || notification.options.key === key
? { ...notification, dismissed: true }
: { ...notification },
),
);
},
[setNotifications],
);
const remove = useCallback(
(key: SnackbarKey) => {
setNotifications((notifications) =>
notifications.filter((notification) => notification.options.key !== key),
);
},
[setNotifications],
);
const actions = useMemo(() => ({ push, close, remove }), [push, close, remove]);
return [notifications, actions];
}
export default useNotifications;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment