Skip to content

Commit

Permalink
feat(toast): add stop, start timers
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitrsavk committed Jan 22, 2021
1 parent e994512 commit b28ea98
Showing 1 changed file with 73 additions and 8 deletions.
81 changes: 73 additions & 8 deletions packages/toast/src/component.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import React, { forwardRef, useCallback, useEffect, useRef } from 'react';
import React, {
forwardRef,
MouseEventHandler,
useCallback,
useEffect,
useRef,
TouchEventHandler,
} from 'react';
import mergeRefs from 'react-merge-refs';
import { CSSTransition } from 'react-transition-group';
import cn from 'classnames';
Expand All @@ -24,7 +31,7 @@ export type ToastProps = ToastPlateProps &
/**
* Обработчик закрытия компонента
*/
onClose?: () => void;
onClose: () => void;

/**
* Отступ снизу
Expand All @@ -43,6 +50,9 @@ export const Toast = forwardRef<HTMLDivElement, ToastProps>(
className,
bottomOffset,
style = {},
onMouseEnter,
onMouseLeave,
onTouchStart,
onClose,
getPortalContainer,
...restProps
Expand All @@ -53,22 +63,71 @@ export const Toast = forwardRef<HTMLDivElement, ToastProps>(
const timerId = useRef(0);
const prevOpen = usePrevious(open);

const handleClickOutside = useCallback(() => {
const startTimer = useCallback(() => {
clearTimeout(timerId.current);

timerId.current = window.setTimeout(onClose, autoCloseDelay);
}, [autoCloseDelay, onClose]);

const stopTimer = useCallback(() => {
clearTimeout(timerId.current);
}, []);

const handleMouseEnter = useCallback<MouseEventHandler<HTMLDivElement>>(
event => {
stopTimer();

if (onMouseEnter) {
onMouseEnter(event);
}
},
[onMouseEnter, stopTimer],
);

const handleMouseLeave = useCallback<MouseEventHandler<HTMLDivElement>>(
event => {
startTimer();

if (onMouseLeave) {
onMouseLeave(event);
}
},
[onMouseLeave, startTimer],
);

const handleTouchStart = useCallback<TouchEventHandler<HTMLDivElement>>(
event => {
stopTimer();

if (onTouchStart) {
onTouchStart(event);
}
},
[onTouchStart, stopTimer],
);

const handleClickOutside = useCallback(() => {
onClose();
}, [onClose]);
stopTimer();
}, [onClose, stopTimer]);

useClickOutside(plateRef, handleClickOutside);

useEffect(() => {
if (open !== prevOpen && open) {
timerId.current = window.setTimeout(onClose, autoCloseDelay);
startTimer();
}

return () => {
clearTimeout(timerId.current);
stopTimer();
};
}, [autoCloseDelay, open, prevOpen, onClose]);
}, [open, prevOpen, startTimer, stopTimer]);

const callbacks = {
onMouseEnter: handleMouseEnter,
onMouseLeave: handleMouseLeave,
onTouchStart: handleTouchStart,
};

if (anchorElement) {
return (
Expand All @@ -80,7 +139,12 @@ export const Toast = forwardRef<HTMLDivElement, ToastProps>(
popperClassName={styles.popover}
transition={{ timeout: 150 }}
>
<ToastPlate {...restProps} ref={mergeRefs([ref, plateRef])} onClose={onClose} />
<ToastPlate
{...restProps}
ref={mergeRefs([ref, plateRef])}
onClose={onClose}
{...callbacks}
/>
</Popover>
);
}
Expand All @@ -107,6 +171,7 @@ export const Toast = forwardRef<HTMLDivElement, ToastProps>(
...style,
bottom: bottomOffset && `${bottomOffset}px`,
}}
{...callbacks}
/>
</CSSTransition>
</Portal>
Expand Down

0 comments on commit b28ea98

Please sign in to comment.