Skip to content

Commit

Permalink
feat(react/toast): enhance inline toast transition management (#940)
Browse files Browse the repository at this point in the history
* feat: enable toast management through `ToastGroup` without `ToastManager`

* feat: rename `ToastGroup` to `ToastTransitionController`

* docs: update drawer and modal with toast examples

* docs: update toast examples

* docs: update table examples

* test: enhance test coverage for ToastTransitionController

* test: enhance test coverage for `ToastManager`

* feat: update `ToastController` to accept function as children

* feat: update toast examples and remove `ToastTransitionGroup`

* docs: update toast page

* test: enhance test coverage for toast

* test: enhance test coverage for ToastManager

* refactor: improve the render toast function in `ToastManager`

* docs: update ToastManager page

* feat: enhance toast rendering in ToastManager

* chore: remove deprecated `isValidElementType` from `MenuToggleIcon`

* refactor(Stack): refine the code for filtering valid children

* test: improve test coverage for Stack component

* test: improve test coverage for ToastManager
  • Loading branch information
cheton authored Nov 8, 2024
1 parent 2dff356 commit 56d92cd
Show file tree
Hide file tree
Showing 24 changed files with 1,514 additions and 563 deletions.
10 changes: 8 additions & 2 deletions packages/react-docs/pages/components/table/index.page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ Below are the code snippets that demonstrate how to render the expanded row base
<TableCell>Cell 3</TableCell>
</TableRow>
{row.getCanExpand() && (
<Collapse in={row.getIsExpanded()}>
<Collapse
in={row.getIsExpanded()}
unmountOnExit
>
{renderExpandedRow({ row })}
</Collapse>
)}
Expand All @@ -102,7 +105,10 @@ Below are the code snippets that demonstrate how to render the expanded row base
borderBottom={0}
colSpan={row.getVisibleCells().length}
>
<Collapse in={row.getIsExpanded()}>
<Collapse
in={row.getIsExpanded()}
unmountOnExit
>
{renderExpandedRow({ row })}
</Collapse>
</TableCell>
Expand Down
10 changes: 8 additions & 2 deletions packages/react-docs/pages/components/table/row-expanding.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,10 @@ const App = () => {
})}
</TableRow>
{(row.getCanExpand() && layout === 'flexbox') && (
<Collapse in={row.getIsExpanded()}>
<Collapse
in={row.getIsExpanded()}
unmountOnExit
>
{renderExpandedRow({ row })}
</Collapse>
)}
Expand All @@ -251,7 +254,10 @@ const App = () => {
borderBottom={0}
colSpan={row.getVisibleCells().length}
>
<Collapse in={row.getIsExpanded()}>
<Collapse
in={row.getIsExpanded()}
unmountOnExit
>
{renderExpandedRow({ row })}
</Collapse>
</TableCell>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import { useToastManager } from '@tonic-ui/react';
function MyComponent() {
const toast = useToastManager();
const handleClickOpenToast = () => {
const render = ({ onClose, placement }) => {
const render = ({ id, data, onClose, placement }) => {
const isTop = placement.includes('top');
const toastSpacingKey = isTop ? 'pb' : 'pt';
const styleProps = {
Expand All @@ -54,7 +54,7 @@ function MyComponent() {

return (
<Box sx={styleProps}>
<Toast isClosable onClose={onClose}>
<Toast data-toast-id={id} isClosable onClose={onClose}>
This is a toast notification
</Toast>
</Box>
Expand All @@ -63,6 +63,7 @@ function MyComponent() {
const options = {
placement: 'bottom-right',
duration: 5000,
data: {}, // user-defined data
};
toast(render, options);
};
Expand All @@ -75,19 +76,19 @@ function MyComponent() {
}
```

The `toast` method takes a function that returns the toast element to be displayed. The function can also receive an `onClose` function and the `placement` string. The `onClose` function can be used to remove the toast when the user clicks on a close button or after a certain time period.
The `toast` method accepts a function that generates the toast element to display. This function receives `id`, `data`, `onClose`, and `placement` as arguments.

```jsx disabled
const id = toast(({ onClose, placement }) => (
toast(({ id, data, onClose, placement }) => (
<Toast isClosable onClose={onClose}>
This is a toast notification
</Toast>
));
```

To remove a toast, you can either call the `onClose` function or use the `toast.remove` method, which takes the toast's unique id as an argument.
To remove a toast, you can use the `onClose` function, triggered by the user clicking a close button. Alternatively, you can use the `toast.remove` method, passing the toast's unique id as an argument.

```jsx disabled
```js
toast.remove(id);
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import React, { useCallback } from 'react';
const App = () => {
const toast = useToastManager();
const handleClickOpenToast = useCallback(() => {
const render = ({ onClose, placement }) => {
const render = ({ id, data, onClose, placement }) => {
const isTop = placement.includes('top');
const toastSpacingKey = isTop ? 'pb' : 'pt';
const styleProps = {
Expand All @@ -20,14 +20,17 @@ const App = () => {

return (
<Box sx={styleProps}>
<Toast isClosable onClose={onClose}>
<Toast data-toast-id={id} isClosable onClose={onClose}>
<Text>This is a toast notification</Text>
</Toast>
</Box>
);
};
const options = {
placement: 'bottom-right',
data: {
foo: 'bar',
},
duration: 5000,
};
toast(render, options);
Expand Down
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)*: 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)*: 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 @@ -155,10 +156,13 @@ Example usage with a state object:
toast.setState({
'top': [
{
id: '2',
id: 1,
content: ({ id, data, onClose, placement }) => (
<Toast data-toast-id={id} isClosable onClose={onClose}>
This is a toast
</Toast>
),
duration: 3000,
message: 'New toast message',
onClose: () => toast.close('2'),
placement: 'top',
}
],
Expand All @@ -178,10 +182,13 @@ toast.setState(prevState => ({
'top': [
...prevState['top'],
{
id: '2',
id: 1,
content: ({ id, data, onClose, placement }) => (
<Toast data-toast-id={id} isClosable onClose={onClose}>
This is a toast
</Toast>
),
duration: null,
message: 'New toast message',
onClose: () => toast.close('2', 'top'),
placement: 'top',
},
],
Expand All @@ -196,10 +203,16 @@ 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 data-toast-id={id} isClosable onClose={onClose}>
This is a toast
</Toast>
),
data: {
// 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
Loading

0 comments on commit 56d92cd

Please sign in to comment.