Skip to content

Commit

Permalink
Respect options in useToaster
Browse files Browse the repository at this point in the history
- Apply default duration to toast delays
- Move pause into own state
  • Loading branch information
timolins committed Dec 21, 2020
1 parent 4bc014e commit 2cb8c2d
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/components/toaster.tsx
Expand Up @@ -22,7 +22,7 @@ export const Toaster: React.FC<ToasterProps> = ({
containerStyle,
toastOptions,
}) => {
const { toasts, handlers } = useToaster();
const { toasts, handlers } = useToaster(toastOptions);

return (
<div
Expand Down
2 changes: 1 addition & 1 deletion src/core/store.ts
Expand Up @@ -109,7 +109,7 @@ export const reducer = (state: State, action: Action): State => {
pausedAt: undefined,
toasts: state.toasts.map((t) => ({
...t,
duration: t.duration + diff,
pauseDuration: t.pauseDuration + diff,
})),
};
}
Expand Down
9 changes: 1 addition & 8 deletions src/core/toast.ts
Expand Up @@ -10,13 +10,6 @@ import {
import { genId } from './utils';
import { dispatch, ActionType } from './store';

const defaultTimeouts: Map<ToastType, number> = new Map<ToastType, number>([
['blank', 4000],
['error', 4000],
['success', 2000],
['loading', 30000],
]);

type Message = ValueOrFunction<Renderable, Toast>;

type ToastHandler = (message: Message, options?: ToastOptions) => string;
Expand All @@ -32,8 +25,8 @@ const createToast = (
type,
role: 'status',
ariaLive: 'polite',
duration: defaultTimeouts.get(type) || 4000,
message,
pauseDuration: 0,
...opts,
});

Expand Down
3 changes: 2 additions & 1 deletion src/core/types.ts
Expand Up @@ -36,7 +36,8 @@ export interface Toast {
id: string;
message: ValueOrFunction<Renderable, Toast>;
icon?: Renderable;
duration: number;
duration?: number;
pauseDuration: number;

role: 'status' | 'alert';
ariaLive: 'assertive' | 'off' | 'polite';
Expand Down
22 changes: 18 additions & 4 deletions src/core/use-toaster.ts
@@ -1,7 +1,15 @@
import { useEffect, useMemo } from 'react';
import { dispatch, ActionType, useStore } from './store';
import { DefaultToastOptions, ToastType } from './types';

export const useToaster = () => {
const defaultTimeouts: Map<ToastType, number> = new Map<ToastType, number>([
['blank', 4000],
['error', 4000],
['success', 2000],
['loading', 30000],
]);

export const useToaster = (toastOptions?: DefaultToastOptions) => {
const { toasts, pausedAt } = useStore();
const visibleToasts = toasts.filter((t) => t.visible);

Expand All @@ -12,7 +20,13 @@ export const useToaster = () => {

const now = Date.now();
const timeouts = toasts.map((t) => {
const duration = t.duration - (now - t.createdAt);
const duration =
t.duration ||
toastOptions?.duration ||
defaultTimeouts.get(t.type) ||
4000;
const durationLeft = duration + t.pauseDuration - (now - t.createdAt);

const dismiss = () => {
dispatch({
type: ActionType.DISMISS_TOAST,
Expand All @@ -26,13 +40,13 @@ export const useToaster = () => {
}, 1000);
};

if (duration < 0) {
if (durationLeft < 0) {
if (t.visible) {
dismiss();
}
return;
}
return setTimeout(dismiss, duration);
return setTimeout(dismiss, durationLeft);
});

return () => {
Expand Down

0 comments on commit 2cb8c2d

Please sign in to comment.