Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Chore: refactor NotificationsProvider to use React.Transition.onExite…
…d to remove Notifications from Queue
  • Loading branch information
dchae committed May 23, 2025
commit 27b6f9305f91f9e8b843c0f4885a140d84909770
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ import type {
} from './useNotifications';
import { useLocaleText, type LocaleText } from '../AppProvider/LocalizationProvider';

export interface RemoveClosedNotifications {
/**
* Remove all closed snackbars from the NotificationsState queue.
*/
(): void;
}

export interface NotificationsProviderSlotProps {
snackbar: SnackbarProps;
}
Expand Down Expand Up @@ -55,7 +62,7 @@ interface NotificationProps {
function Notification({ notificationKey, open, message, options, badge }: NotificationProps) {
const globalLocaleText = useLocaleText();
const localeText = { ...defaultLocaleText, ...globalLocaleText };
const { close } = useNonNullableContext(NotificationsContext);
const { close, removeClosed } = useNonNullableContext(NotificationsContext);

const { severity, actionText, onAction, autoHideDuration } = options;

Expand All @@ -69,6 +76,10 @@ function Notification({ notificationKey, open, message, options, badge }: Notifi
[notificationKey, close],
);

const handleExited = React.useCallback(() => {
removeClosed();
}, [removeClosed]);

const action = (
<React.Fragment>
{onAction ? (
Expand All @@ -90,6 +101,7 @@ function Notification({ notificationKey, open, message, options, badge }: Notifi

const props = React.useContext(RootPropsContext);
const SnackbarComponent = props?.slots?.snackbar ?? Snackbar;
const externalTransitionProps = props?.slotProps?.snackbar?.slotProps?.transition;
const snackbarSlotProps = useSlotProps({
elementType: SnackbarComponent,
ownerState: props,
Expand All @@ -99,6 +111,12 @@ function Notification({ notificationKey, open, message, options, badge }: Notifi
autoHideDuration,
onClose: handleClose,
action,
slotProps: {
transition: {
...externalTransitionProps,
onExited: handleExited,
},
},
},
});

Expand Down Expand Up @@ -195,16 +213,19 @@ function NotificationsProvider(props: NotificationsProviderProps) {
...prev,
queue: prev.queue.map((n) => (n.notificationKey === key ? { ...n, open: false } : n)),
}));
}, []);

setTimeout(() => {
setState((prev) => ({
...prev,
queue: prev.queue.filter((n) => n.open),
}));
}, 100);
const removeClosed = React.useCallback<RemoveClosedNotifications>(() => {
setState((prev) => ({
...prev,
queue: prev.queue.filter((n) => n.open),
}));
}, []);

const contextValue = React.useMemo(() => ({ show, close }), [show, close]);
const contextValue = React.useMemo(
() => ({ show, close, removeClosed }),
[show, close, removeClosed],
);

return (
<RootPropsContext.Provider value={props}>
Expand Down