Skip to content

Commit

Permalink
Use MutationObserver to update on height change
Browse files Browse the repository at this point in the history
  • Loading branch information
timolins committed Jul 17, 2022
1 parent 59e475c commit 9eddc26
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 30 deletions.
17 changes: 13 additions & 4 deletions src/components/toaster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,25 @@ const ToastWrapper = ({
id,
className,
style,
onHeightGetter,
onHeightUpdate,
children,
}: ToastWrapperProps) => {
const ref = React.useCallback(
(el: HTMLElement | null) => {
if (el) {
onHeightGetter(id, () => el.getBoundingClientRect().height);
const updateHeight = () => {
const height = el.getBoundingClientRect().height;
onHeightUpdate(id, height);
};
updateHeight();
new MutationObserver(updateHeight).observe(el, {
subtree: true,
childList: true,
characterData: true,
});
}
},
[onHeightGetter]
[id, onHeightUpdate]
);

return (
Expand Down Expand Up @@ -113,7 +122,7 @@ export const Toaster: React.FC<ToasterProps> = ({
<ToastWrapper
id={t.id}
key={t.id}
onHeightGetter={handlers.setHeightGetter}
onHeightUpdate={handlers.updateHeight}
className={t.visible ? activeClass : ''}
style={positionStyle}
>
Expand Down
3 changes: 1 addition & 2 deletions src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ export interface Toast {
createdAt: number;
visible: boolean;
height?: number;
getHeight?: () => number;
}

export type ToastOptions = Partial<
Expand Down Expand Up @@ -87,6 +86,6 @@ export interface ToastWrapperProps {
id: string;
className?: string;
style?: React.CSSProperties;
onHeightGetter: (id: string, getHeight: () => number) => void;
onHeightUpdate: (id: string, height: number) => void;
children?: React.ReactNode;
}
27 changes: 3 additions & 24 deletions src/core/use-toaster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,10 @@ import { dispatch, ActionType, useStore } from './store';
import { toast } from './toast';
import { DefaultToastOptions, Toast, ToastPosition } from './types';

// Prevent useLayoutEffect warning from being used on the the server
const useIsomorphicLayoutEffect =
typeof window !== 'undefined' ? useLayoutEffect : useEffect;

export const setHeightGetter = (toastId: string, getHeight: () => number) => {
export const updateHeight = (toastId: string, height: number) => {
dispatch({
type: ActionType.UPDATE_TOAST,
toast: { id: toastId, getHeight },
toast: { id: toastId, height },
});
};
const startPause = () => {
Expand Down Expand Up @@ -88,27 +84,10 @@ export const useToaster = (toastOptions?: DefaultToastOptions) => {
[toasts]
);

useIsomorphicLayoutEffect(() => {
for (const t of toasts) {
if (!t.visible || !t.getHeight) {
return;
}

const height = t.getHeight();

if (height !== t.height) {
dispatch({
type: ActionType.UPDATE_TOAST,
toast: { id: t.id, height },
});
}
}
}, [toasts]);

return {
toasts,
handlers: {
setHeightGetter,
updateHeight,
startPause,
endPause,
calculateOffset,
Expand Down

0 comments on commit 9eddc26

Please sign in to comment.