Skip to content

Commit

Permalink
feat: update toast examples and remove ToastTransitionGroup
Browse files Browse the repository at this point in the history
  • Loading branch information
cheton committed Nov 7, 2024
1 parent 531fe6c commit 5c7ad10
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 184 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,24 @@ const toast = useToastManager();

The `useToastManager` Hook returns an object with the following methods and properties:

### toast(message, [options={'{}'}])
### toast(content, [options={'{}'}])

Create a toast at the specified placement and return the toast id.

#### Aliases

<dl>
<dd>*toast.notify(message, [options={'{}'}])*</dd>
<dd>*toast.notify(content, [options={'{}'}])*</dd>
</dl>

#### Parameters

<dl>
<dd>`message` *(Function|string)*: The toast message to render.</dd>
<dd>`content` *(Function|string)*: The toast content to render.</dd>
<dd>`[options={}]` *(Object)*: The options object.</dd>
<dd>`[options.data]` *(any)*: The user-defined data supplied to the toast.</dd>
<dd>`[options.duration=null]` *(number)*: The duration (in milliseconds) that the toast should remain on the screen. If set to null, toast will never dismiss.</dd>
<dd>`[options.id]` *(string)*: A unique ID of the toast.</dd>
<dd>`[options.id]` *(string)*: A unique identifier that represents the toast.</dd>
<dd>`[options.placement]` *(string)*: The placement of the toast.</dd>
</dl>

Expand Down Expand Up @@ -117,8 +117,9 @@ Update a specific toast with new options based on the given toast id.
<dl>
<dd>`id` *(string)*: The id to update the toast.</dd>
<dd>`[options={}]` *(Object)*: The options object.</dd>
<dd>`[options.content]` *(Function|string)*: The toast content to render.</dd>
<dd>`[options.data]` *(any)*: The user-defined data supplied to the toast.</dd>
<dd>`[options.duration=null]` *(number)*: The duration (in milliseconds) that the toast should remain on the screen. If set to null, toast will never dismiss.</dd>
<dd>`[options.message]` *(Function|string)*: The toast message to render.</dd>
</dl>

#### Returns
Expand All @@ -133,7 +134,7 @@ Specify the placement to place the toast. The default placement will be used if

### toast.setState(state | updater)

The `setState` method is used to modify the internal state of the toast manager. It provides the ability to add, remove, or update toast messages.
The `setState` method is used to modify the internal state of the toast manager. It provides the ability to add, remove, or update toast content.

#### Parameters

Expand All @@ -156,9 +157,9 @@ toast.setState({
'top': [
{
id: '2',
content: 'New toast',
data: undefined,
duration: 3000,
message: 'New toast message',
onClose: () => toast.close('2'),
placement: 'top',
}
],
Expand All @@ -179,9 +180,9 @@ toast.setState(prevState => ({
...prevState['top'],
{
id: '2',
content: 'New toast',
data: undefined,
duration: null,
message: 'New toast message',
onClose: () => toast.close('2', 'top'),
placement: 'top',
},
],
Expand All @@ -196,10 +197,10 @@ The toast state is a placement object, each placement contains an array of objec
{
'top': [
{
id: '1', // A unique identifier that represents the toast message
id: '1', // A unique identifier that represents the toast
content: ({ id, data, onClose, placement }) => <Toast />, // The toast content to render
data: undefined, // The user-defined data supplied to the toast
duration: null, // The duration (in milliseconds) that the toast should remain on the screen. If set to null, toast will never dismiss.
message: ({ id, onClose, placement }) => <Toast />, // The toast message to render
onClose: () => toast.close(id, placement), // The function to close the toast
placement: 'top', // The placement of the toast
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import {
Stack,
Text,
Toast,
ToastController,
ToastTransition,
ToastTransitionGroup,
ToastTransitionController,
useColorStyle,
} from '@tonic-ui/react';
import { CloseSIcon } from '@tonic-ui/react-icons';
Expand Down Expand Up @@ -152,29 +153,35 @@ const App = () => {
>
<InlineToastContainer>
<ToastTransitionGroup>
{toasts.map(toast => (
<ToastTransitionController
key={toast.id}
duration={toast.duration}
onClose={createCloseToastHandler(toast.id)}
>
{({ onClose }) => (
<Toast
appearance={toast.appearance}
isClosable={true}
{toasts.map(toast => {
const onClose = createCloseToastHandler(toast.id);
return (
<ToastTransition
key={toast.id}
in
unmountOnExit
>
<ToastController
duration={toast.duration}
onClose={onClose}
sx={{
mb: '2x',
minWidth: 280, // The toast has a minimum width of 280 pixels
width: 'fit-content',
boxShadow: colorStyle.shadow.thin,
}}
>
{toast.content}
</Toast>
)}
</ToastTransitionController>
))}
<Toast
appearance={toast.appearance}
isClosable={true}
onClose={onClose}
sx={{
mb: '2x',
minWidth: 280, // The toast has a minimum width of 280 pixels
width: 'fit-content',
boxShadow: colorStyle.shadow.thin,
}}
>
{toast.content}
</Toast>
</ToastController>
</ToastTransition>
);
})}
</ToastTransitionGroup>
</InlineToastContainer>
<DrawerHeader>
Expand Down
96 changes: 61 additions & 35 deletions packages/react-docs/pages/components/toast/index.page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
ToastCloseButton,
ToastController,
ToastTransition,
ToastTransitionController,
ToastTransitionGroup,
} from '@tonic-ui/react';
```
Expand Down Expand Up @@ -100,7 +99,7 @@ const InlineToastContainer = (props) => (
```jsx
<Toast
appearance="success"
isClosable={true}
isClosable
onClose={onClose}
sx={{
mb: '2x',
Expand Down Expand Up @@ -135,34 +134,71 @@ Example toast object:
```

Here is a complete example:
```js
const idRef = useRef(0);
const [toasts, setToasts] = useState([]);
const notify = (options) => {
const {
appearance,
content,
duration,
} = { ...options };

setToasts(prevState => {
const id = ++(idRef.current);
// You can decide how many toasts you want to show at the same time depending on your use case
const nextState = [
...prevState.slice(MAX_TOASTS > 1 ? -(MAX_TOASTS - 1) : prevState.length),
{
id,
appearance,
content,
duration,
},
];
return nextState;
});
};
const closeToast = (id) => {
setToasts(toasts => toasts.filter(x => x.id !== id));
};
const createCloseToastHandler = (id) => () => {
closeToast(id);
};
```

```jsx
<InlineToastContainer>
<ToastTransitionGroup>
{toasts.map(toast => (
<ToastTransitionController
key={toast.id}
duration={toast.duration}
onClose={() => {
setToasts(toasts => toasts.filter(x => x.id !== id));
}}
>
{({ onClose }) => (
<Toast
appearance={toast.appearance}
isClosable={true}
{toasts.map(toast => {
const onClose = createCloseToastHandler(toast.id);
return (
<ToastTransition
key={toast.id}
in
unmountOnExit
>
<ToastController
duration={toast.duration}
onClose={onClose}
sx={{
mb: '2x',
minWidth: 280, // The toast has a minimum width of 280 pixels
width: 'fit-content',
boxShadow: colorStyle.shadow.thin,
}}
>
{toast.content}
</Toast>
)}
</ToastTransitionController>
))}
<Toast
appearance={toast.appearance}
isClosable
onClose={onClose}
sx={{
mb: '2x',
minWidth: 280, // The toast has a minimum width of 280 pixels
width: 'fit-content',
boxShadow: colorStyle.shadow.thin,
}}
>
{toast.content}
</Toast>
</ToastController>
</ToastTransition>
);
})}
</ToastTransitionGroup>
</InlineToastContainer>
```
Expand Down Expand Up @@ -213,16 +249,6 @@ Here is a complete example:
| timeout | number \| `{ appear?: number, enter?: number, exit?: number }` | `{ enter: duration.standard, exit: duration.standard }` | The duration for the transition, in milliseconds. You may specify a single timeout for all transitions, or individually with an object. |
| unmountOnExit | boolean | | If `true`, it will unmount the child component when `in={false}` and the animation has finished. By default the child component stays mounted after it reaches the 'exited' state. |

### ToastTransitionController

| Name | Type | Default | Description |
| :--- | :--- | :------ | :---------- |
| TransitionComponent | ElementType | ToastTransition | The component used for the transition. |
| TransitionProps | object | | Props applied to the [Transition](http://reactcommunity.org/react-transition-group/transition#Transition-props) element. |
| children | ReactNode | ReactNode \| `({ onClose }) => ReactNode` | A function child can be used intead of a React element. This function is invoked with an object that includes the `onClose` prop. |
| duration | number | null | The duration in milliseconds after which the toast will be automatically closed. Set to `null` to disable auto-closing. |
| onClose | function | | A callback called when the toast is being closed. |

### ToastTransitionGroup

| Name | Type | Default | Description |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
Stack,
Text,
Toast,
ToastTransitionController,
ToastController,
ToastTransition,
ToastTransitionGroup,
useColorStyle,
} from '@tonic-ui/react';
Expand Down Expand Up @@ -152,29 +153,35 @@ const App = () => {
>
<InlineToastContainer>
<ToastTransitionGroup>
{toasts.map(toast => (
<ToastTransitionController
key={toast.id}
duration={toast.duration}
onClose={createCloseToastHandler(toast.id)}
>
{({ onClose }) => (
<Toast
appearance={toast.appearance}
isClosable={true}
{toasts.map(toast => {
const onClose = createCloseToastHandler(toast.id);
return (
<ToastTransition
key={toast.id}
in
unmountOnExit
>
<ToastController
duration={toast.duration}
onClose={onClose}
sx={{
mb: '2x',
minWidth: 280, // The toast has a minimum width of 280 pixels
width: 'fit-content',
boxShadow: colorStyle.shadow.thin,
}}
>
{toast.content}
</Toast>
)}
</ToastTransitionController>
))}
<Toast
appearance={toast.appearance}
isClosable={true}
onClose={onClose}
sx={{
mb: '2x',
minWidth: 280, // The toast has a minimum width of 280 pixels
width: 'fit-content',
boxShadow: colorStyle.shadow.thin,
}}
>
{toast.content}
</Toast>
</ToastController>
</ToastTransition>
);
})}
</ToastTransitionGroup>
</InlineToastContainer>
<ModalHeader>
Expand Down
1 change: 0 additions & 1 deletion packages/react/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,6 @@ test('should match expected exports', () => {
'ToastManager',
'ToastMessage',
'ToastTransition',
'ToastTransitionController',
'ToastTransitionGroup',
'useToastManager',

Expand Down
7 changes: 2 additions & 5 deletions packages/react/src/toast/ToastController.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { useMergeRefs } from '@tonic-ui/react-hooks';
import { callEventHandlers, runIfFn } from '@tonic-ui/utils';
import { callEventHandlers } from '@tonic-ui/utils';
import React, { forwardRef, useCallback, useRef, useState } from 'react';
import { Box } from '../box';
import { useDefaultProps } from '../default-props';
import useTimeout from '../utils/useTimeout';

const ToastController = forwardRef((inProps, ref) => {
const {
children,
duration: durationProp = null,
onClose: onCloseProp,
onMouseEnter: onMouseEnterProp,
Expand All @@ -32,9 +31,7 @@ const ToastController = forwardRef((inProps, ref) => {
onMouseEnter={callEventHandlers(onMouseEnterProp, onMouseEnter)}
onMouseLeave={callEventHandlers(onMouseLeaveProp, onMouseLeave)}
{...rest}
>
{runIfFn(children, { onClose: onCloseProp })}
</Box>
/>
);
});

Expand Down
Loading

0 comments on commit 5c7ad10

Please sign in to comment.