Skip to content

Commit

Permalink
feat: added ability to add a custom timeout (#892)
Browse files Browse the repository at this point in the history
Co-authored-by: Clinton Medbery <[email protected]>
  • Loading branch information
seialkali and clintonmedbery authored Dec 2, 2022
1 parent 5bbd80e commit 070d362
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 9 deletions.
10 changes: 7 additions & 3 deletions packages/toaster/components/Toaster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@ import { ToastProps } from "./Toast";
import { toaster, preTransitionStyle, transitionStyles } from "../style";
import { margin, marginAt, listReset } from "../../shared/styles/styleUtils";

export const DELAY_TIME = 3000;
export const DEFAULT_DELAY_TIME = 3000;
const MARGINAL_DELAY = 1000;
const animationDuration = 300;

type Toast = React.ReactElement<ToastProps>;

interface ToasterProps {
dismissTime?: number;
children?: Toast | Toast[];
}

const Toaster = ({ children }: ToasterProps) => {
const Toaster = ({
dismissTime = DEFAULT_DELAY_TIME,
children
}: ToasterProps) => {
const timeouts = React.useRef<number[]>([]);

const [toasts, setToasts] = React.useState<Toast[]>([]);
Expand All @@ -35,7 +39,7 @@ const Toaster = ({ children }: ToasterProps) => {
timeouts.current.push(
window.setTimeout(() => {
dismissToast(toast);
}, DELAY_TIME + MARGINAL_DELAY * index)
}, dismissTime + MARGINAL_DELAY * index)
);
}
});
Expand Down
35 changes: 35 additions & 0 deletions packages/toaster/stories/Toaster.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,41 @@ export const AutoDismiss = () => {
);
};

export const CustomDismissTimeAutoDismiss = () => {
const [toasts, setToasts] = React.useState<number[]>([]);

const removeToast = (id: number) => {
setToasts(toasts => toasts.filter(toast => toast !== id));
};

const handleToastAdd = () => {
const newToastId = addedToastId++;
setToasts(toasts => [...toasts, newToastId]);
};

return (
<div>
<Toaster dismissTime={5000}>
{toasts.map(toastId => {
const handleDismiss = () => {
removeToast(toastId);
};
return (
<Toast
autodismiss
id={`toast-${toastId}`}
key={toastId}
title={`New message ${toastId} disappearing in 5 seconds`}
onDismiss={handleDismiss}
/>
);
})}
</Toaster>
<button onClick={handleToastAdd}>Make me toast</button>
</div>
);
};

export const WithDismissCallback = () => (
<Toaster>
{[
Expand Down
40 changes: 34 additions & 6 deletions packages/toaster/tests/Toaster.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
waitForElementToBeRemoved
} from "@testing-library/react";
import { Toaster, Toast } from "../";
import { DELAY_TIME } from "../components/Toaster";
import { DEFAULT_DELAY_TIME } from "../components/Toaster";
import userEvent from "@testing-library/user-event";

describe("Toaster", () => {
Expand Down Expand Up @@ -53,7 +53,7 @@ describe("Toaster", () => {
expect(dismissCallback).toHaveBeenCalledTimes(1);
});

it("dismisses autodismiss toasts after specified time", async () => {
it("dismisses autodismiss toasts after a default time", async () => {
jest.useFakeTimers();
const title = "I Am Toast";
const { getByText, queryByText } = render(
Expand All @@ -64,8 +64,36 @@ describe("Toaster", () => {

expect(getByText(title)).toBeDefined();

await waitFor(() => {
expect(queryByText(title)).toBeInTheDocument();
});

act(() => {
jest.advanceTimersByTime(DEFAULT_DELAY_TIME);
});

await waitFor(() => {
expect(queryByText(title)).not.toBeInTheDocument();
});
});

it("dismisses autodismiss toasts after specified time", async () => {
jest.useFakeTimers();
const title = "I Am Toast";
const { getByText, queryByText } = render(
<Toaster dismissTime={8000}>
<Toast id={0} autodismiss title={title} key={0} />
</Toaster>
);

expect(getByText(title)).toBeDefined();

await waitFor(() => {
expect(queryByText(title)).toBeInTheDocument();
});

act(() => {
jest.advanceTimersByTime(DELAY_TIME);
jest.advanceTimersByTime(8000);
});

await waitFor(() => {
Expand All @@ -87,7 +115,7 @@ describe("Toaster", () => {
fireEvent.mouseEnter(toasterList);

act(() => {
jest.advanceTimersByTime(DELAY_TIME);
jest.advanceTimersByTime(DEFAULT_DELAY_TIME);
});

// is never removed because timeout was cleared
Expand All @@ -98,7 +126,7 @@ describe("Toaster", () => {
fireEvent.mouseLeave(toasterList);

act(() => {
jest.advanceTimersByTime(DELAY_TIME);
jest.advanceTimersByTime(DEFAULT_DELAY_TIME);
});

await waitFor(() => {
Expand All @@ -123,7 +151,7 @@ describe("Toaster", () => {
expect(dismissCallback).not.toHaveBeenCalled();

act(() => {
jest.advanceTimersByTime(DELAY_TIME);
jest.advanceTimersByTime(DEFAULT_DELAY_TIME);
});

expect(dismissCallback).toHaveBeenCalledTimes(1);
Expand Down

0 comments on commit 070d362

Please sign in to comment.