Skip to content

Commit 60a67fa

Browse files
committed
pr review
1 parent 5f2e2e6 commit 60a67fa

4 files changed

Lines changed: 69 additions & 51 deletions

File tree

packages/react-components/react-toast/src/components/ToastContainer/useToastContainer.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ export const useToastContainer_unstable = (
4848
} = props;
4949
const toastRef = React.useRef<HTMLDivElement | null>(null);
5050
const { targetDocument } = useFluent_unstable();
51-
// const { play, toastRef } = useToast<HTMLDivElement>({ ...props });
5251
const [running, setRunning] = React.useState(false);
5352
const pause = useEventCallback(() => setRunning(false));
5453
const play = useEventCallback(() => setRunning(true));
@@ -61,14 +60,11 @@ export const useToastContainer_unstable = (
6160
if (pauseOnWindowBlur) {
6261
targetDocument.defaultView?.addEventListener('focus', play);
6362
targetDocument.defaultView?.addEventListener('blur', pause);
64-
}
65-
66-
return () => {
67-
if (pauseOnWindowBlur) {
63+
return () => {
6864
targetDocument.defaultView?.removeEventListener('focus', play);
6965
targetDocument.defaultView?.removeEventListener('blur', pause);
70-
}
71-
};
66+
};
67+
}
7268
}, [targetDocument, pause, play, pauseOnWindowBlur]);
7369

7470
React.useEffect(() => {

packages/react-components/react-toast/src/state/useToaster.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,22 @@ describe('useToaster', () => {
4545
expect(toaster.dismissAllToasts).toHaveBeenCalledTimes(1);
4646
expect(toaster.dismissToast).toHaveBeenCalledTimes(1);
4747
});
48+
49+
it('should respect toasterId for events', () => {
50+
const toaster = mockToaster();
51+
renderHook(() => useToaster({ toasterId: 'foo' }));
52+
53+
const detail = { toasterId: 'bar' };
54+
act(() => {
55+
document.dispatchEvent(new CustomEvent(EVENTS.dismiss, { detail }));
56+
document.dispatchEvent(new CustomEvent(EVENTS.update, { detail }));
57+
document.dispatchEvent(new CustomEvent(EVENTS.dismissAll, { detail }));
58+
document.dispatchEvent(new CustomEvent(EVENTS.show, { detail }));
59+
});
60+
61+
expect(toaster.buildToast).toHaveBeenCalledTimes(0);
62+
expect(toaster.updateToast).toHaveBeenCalledTimes(0);
63+
expect(toaster.dismissAllToasts).toHaveBeenCalledTimes(0);
64+
expect(toaster.dismissToast).toHaveBeenCalledTimes(0);
65+
});
4866
});

packages/react-components/react-toast/src/state/useToaster.ts

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@ import * as React from 'react';
22
import { useEventCallback, useForceUpdate } from '@fluentui/react-utilities';
33
import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
44
import { createToaster } from './vanilla';
5-
import { Toast, ToastListenerMap, ToastPosition, ToasterId, ToasterOptions } from './types';
5+
import type {
6+
CommonToastDetail,
7+
ShowToastEventDetail,
8+
Toast,
9+
ToastListenerMap,
10+
ToastPosition,
11+
ToasterId,
12+
ToasterOptions,
13+
} from './types';
614
import { ToasterProps } from '../components/Toaster';
715
import { EVENTS } from './constants';
816

@@ -21,54 +29,51 @@ export function useToaster<TElement extends HTMLElement>(options: ToasterProps =
2129
return;
2230
}
2331

24-
const buildToast: ToastListenerMap[typeof EVENTS.show] = e => {
25-
if (!isCorrectToaster(e.detail.toasterId)) {
26-
return;
27-
}
32+
const addToastListener = <TType extends keyof ToastListenerMap>(
33+
eventType: TType,
34+
callback: ToastListenerMap[TType],
35+
) => {
36+
const listener: ToastListenerMap[TType] = (e: CustomEvent<CommonToastDetail>) => {
37+
if (!isCorrectToaster(e.detail.toasterId)) {
38+
return;
39+
}
40+
41+
callback(e as CustomEvent<ShowToastEventDetail>);
42+
forceUpdate();
43+
};
44+
45+
targetDocument.addEventListener(eventType, listener as () => void);
46+
return () => targetDocument.removeEventListener(eventType, listener as () => void);
47+
};
2848

49+
const buildToast: ToastListenerMap[typeof EVENTS.show] = e => {
2950
toaster.buildToast(e.detail, forceUpdate);
30-
forceUpdate();
3151
};
3252

3353
const dismissToast: ToastListenerMap[typeof EVENTS.dismiss] = e => {
34-
if (!isCorrectToaster(e.detail.toasterId)) {
35-
return;
36-
}
37-
3854
toaster.dismissToast(e.detail.toastId);
39-
forceUpdate();
4055
};
4156

4257
const updateToast: ToastListenerMap[typeof EVENTS.update] = e => {
43-
if (!isCorrectToaster(e.detail.toasterId)) {
44-
return;
45-
}
46-
4758
toaster.updateToast(e.detail);
48-
forceUpdate();
4959
};
5060

5161
const dismissAllToasts: ToastListenerMap[typeof EVENTS.dismissAll] = e => {
52-
if (!isCorrectToaster(e.detail.toasterId)) {
53-
return;
54-
}
55-
5662
toaster.dismissAllToasts();
57-
forceUpdate();
5863
};
5964

60-
targetDocument.addEventListener(EVENTS.show, buildToast as () => void);
61-
targetDocument.addEventListener(EVENTS.dismiss, dismissToast as () => void);
62-
targetDocument.addEventListener(EVENTS.update, updateToast as () => void);
63-
targetDocument.addEventListener(EVENTS.dismissAll, dismissAllToasts as () => void);
65+
const cleanupBuildListener = addToastListener(EVENTS.show, buildToast);
66+
const cleanupUpdateListener = addToastListener(EVENTS.update, updateToast);
67+
const cleanupDismissListener = addToastListener(EVENTS.dismiss, dismissToast);
68+
const cleanupDismissAllListener = addToastListener(EVENTS.dismissAll, dismissAllToasts);
6469

6570
return () => {
66-
targetDocument.removeEventListener(EVENTS.show, buildToast as () => void);
67-
targetDocument.removeEventListener(EVENTS.dismiss, dismissToast as () => void);
68-
targetDocument.removeEventListener(EVENTS.update, updateToast as () => void);
69-
targetDocument.removeEventListener(EVENTS.dismissAll, dismissAllToasts as () => void);
71+
cleanupBuildListener();
72+
cleanupDismissAllListener();
73+
cleanupUpdateListener();
74+
cleanupDismissListener();
7075
};
71-
}, [toaster, forceUpdate, isCorrectToaster, targetDocument]);
76+
}, [toaster, forceUpdate, targetDocument, isCorrectToaster]);
7277

7378
const toastsToRender = (() => {
7479
if (!toaster) {

packages/react-components/react-toast/src/state/vanilla/createToaster.ts

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ function assignDefined<T extends object>(a: Partial<T>, b: Partial<T>) {
1010
}
1111
}
1212
}
13+
const defaulToastOptions: Pick<
14+
ToastOptions,
15+
'priority' | 'pauseOnHover' | 'pauseOnWindowBlur' | 'position' | 'timeout' | 'politeness' | 'onStatusChange'
16+
> = {
17+
onStatusChange: undefined,
18+
priority: 0,
19+
pauseOnHover: false,
20+
pauseOnWindowBlur: false,
21+
position: 'bottom-end',
22+
timeout: 3000,
23+
};
1324

1425
/**
1526
* Toast are managed outside of the react lifecycle because they can be
@@ -20,19 +31,6 @@ export function createToaster(options: Partial<ToasterOptions>) {
2031
const { limit = Number.POSITIVE_INFINITY } = options;
2132
const visibleToasts = new Set<ToastId>();
2233
const toasts = new Map<ToastId, Toast>();
23-
const defaulToastOptions: Pick<
24-
ToastOptions,
25-
'priority' | 'pauseOnHover' | 'pauseOnWindowBlur' | 'position' | 'timeout' | 'politeness' | 'onStatusChange'
26-
> = {
27-
onStatusChange: undefined,
28-
priority: 0,
29-
pauseOnHover: false,
30-
pauseOnWindowBlur: false,
31-
position: 'bottom-end',
32-
timeout: 3000,
33-
};
34-
35-
assignDefined(defaulToastOptions, options);
3634

3735
const queue = createPriorityQueue<ToastId>((ta, tb) => {
3836
const a = toasts.get(ta);
@@ -137,7 +135,8 @@ export function createToaster(options: Partial<ToasterOptions>) {
137135
data: {},
138136
};
139137

140-
assignDefined<Toast>(toast, toastOptions);
138+
assignDefined(toast, options);
139+
assignDefined(toast, toastOptions);
141140

142141
toasts.set(toastId, toast);
143142
toast.onStatusChange?.(null, { status: 'queued', ...toast });

0 commit comments

Comments
 (0)