Skip to content

Commit 34b7e5d

Browse files
committed
feat(useToast): added hook for accessing adding and removal of toasts
1 parent 1452669 commit 34b7e5d

File tree

4 files changed

+119
-0
lines changed

4 files changed

+119
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { options, output } from './useToastHelpers';
2+
import { Meta, Props, Story, Preview } from '@storybook/addon-docs/blocks';
3+
import { LinkTo } from '../../storybook-helpers/mdx';
4+
5+
<Meta title="Hooks/useToast" parameters={{previewTabs: {canvas: {hidden: true}}}} />
6+
7+
# useToast
8+
9+
A hook that provides the context value
10+
of <LinkTo title="Components/ToastProvider" story="Basic">ToastProvider</LinkTo> in
11+
order to add or remove Toast notifications. Make sure that you have a
12+
`ToastProvider` somewhere further up in your React project, or this will not
13+
work.
14+
15+
```ts
16+
const { add, remove } = useToast();
17+
18+
const toastId = add({
19+
heading: 'You are not able to do that',
20+
children: 'The action you are attempting to do is not possible.',
21+
toastType: 'warning',
22+
action: { text: 'Try Again', onClick: tryAgain },
23+
closable: true,
24+
timeout: 4000,
25+
});
26+
27+
// Later, if you want to remove:
28+
remove(toastId);
29+
```
30+
31+
## `ToastContextValue` (return value)
32+
33+
<Props of={output} />
34+
35+
## `AddToast`
36+
37+
<Props of={options} />
38+
39+
## Example
40+
41+
Here's the hook in action:
42+
43+
<Preview>
44+
<Story inline={false} height="550px" id="components-toastprovider--basic" />
45+
</Preview>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { ToastProps } from '../../components';
2+
import { AddToast, ToastContextValue } from '../../hooks/useToast';
3+
import { Include } from '../../utils';
4+
5+
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function */
6+
7+
interface Test extends AddToast, Include<ToastProps, 'heading' | 'children' | 'toastType' | 'action'> {}
8+
9+
export function options(x: Test) {}
10+
export function output(x: ToastContextValue) {}

src/hooks/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ export * from './useFocusTrap';
77
export * from './useKeyForClick';
88
export * from './useManagedFiles';
99
export * from './useOnClick';
10+
export * from './useToast';

src/hooks/useToast.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { createContext, MouseEventHandler, ReactNode, useContext } from 'react';
2+
3+
export interface CommonToastProps {
4+
/**
5+
* The heading to display on the toast. Use this for a brief overview of the
6+
* reason for the toast.
7+
*/
8+
heading: ReactNode;
9+
/**
10+
* The body of the toast. This is where you can elaborate with more
11+
* information about the toast.
12+
*/
13+
children?: ReactNode;
14+
/**
15+
* The type of message the toast is displaying. Will change the color and
16+
* icon of the toast.
17+
* @default "info"
18+
*/
19+
toastType?: 'info' | 'success' | 'warning' | 'error';
20+
/**
21+
* Adds an action button to the toast. Will position to the left of the close
22+
* button if `onClose` was provided.
23+
*/
24+
action?: {
25+
text: ReactNode;
26+
onClick: MouseEventHandler<HTMLButtonElement>;
27+
};
28+
}
29+
30+
export interface AddToast extends CommonToastProps {
31+
/**
32+
* If true, toast will have a close button.
33+
*/
34+
closable?: boolean;
35+
/**
36+
* If provided, will set a timeout for the toast to disappear. This will
37+
* override the `defaultTimeout` prop from `ToastProvider`.
38+
*/
39+
timeout?: number;
40+
}
41+
42+
export interface ToastContextValue {
43+
/**
44+
* Add a toast with parameters outlined by the `AddToast` object.
45+
* @param toast Adds this toast to the end of the queue.
46+
* @returns The ID of the added toast to use for early removal.
47+
*/
48+
add(toast: AddToast): number;
49+
/**
50+
* Remove a toast by ID. If no ID provided, removes the current toast.
51+
* @param toastId The ID of the toast to remove.
52+
*/
53+
remove(toastId?: number): void;
54+
}
55+
56+
export const ToastContext = createContext<ToastContextValue>({} as ToastContextValue);
57+
58+
/**
59+
* Returns the toast context object for managing toasts.
60+
*/
61+
export function useToast() {
62+
return useContext(ToastContext);
63+
}

0 commit comments

Comments
 (0)