diff --git a/README.md b/README.md index f59ef2c..8503083 100644 --- a/README.md +++ b/README.md @@ -11,22 +11,35 @@ React Simple Toasts is a lightweight, user-friendly toast message library for Re

+## Documentation + +Explore the full capabilities of React Simple Toasts and try out live examples in our [documentation page](https://almond-bongbong.github.io/react-simple-toasts/). + +## Key Features + +- **Ease of use**: With a simple installation process and an intuitive API, you can get started with the library in no time. +- **Highly customizable**: You can control various aspects of your toast messages, from their appearance and duration to their behavior upon user interaction. +- **Custom rendering**: The library supports custom rendering, allowing you to tailor the look of your toast messages to match your application's branding. +- **Positioning**: The library allows you to position your toasts at any corner or center of the viewport, offering a high level of control over where your messages appear. +- **Browser compatibility**: The library includes utility functions to ensure that it works seamlessly across different browsers. +- **Interactive**: The library allows toasts to be clickable and to close on click if desired, enabling user interaction. +- **Multiple toasts management**: It provides functionality to manage multiple toasts by controlling the maximum number of visible toasts at a time. + ## Table of Contents - [Installation](#installation) - [Usage](#usage) -- [Live Demo](#live-demo) - [API](#api) - [toast(message, options)](#toastmessage-options) - [Toast Return Object](#toast-return-object) - - [createToast(options)](#createtoastoptions) - - [toastConfig(options)](#toastconfigoptions) + - [Configuring Toasts: createToast and toastConfig](#configuring-toasts-createtoast-and-toastconfig) - [Contributing](#contributing) +- [Support Us](#support-us) - [License](#license) ## Installation -To install the package via npm, run: +Install the package via npm: ```sh npm install react-simple-toasts @@ -34,7 +47,7 @@ npm install react-simple-toasts ## Usage -To utilize React Simple Toasts, invoke the toast function with a message to display: +Import and call the toast function with a message to display: ```jsx import toast from 'react-simple-toasts'; @@ -44,188 +57,27 @@ function MyComponent() { } ``` -By default, the toast message is displayed for 3 seconds. Modify the duration by providing a second argument to the `toast` function: - -```jsx -toast('Hello, world!', 5000); -``` - -Adjust the appearance and behavior of the toast message by supplying an options object to the toast function: - -```jsx -toast('Hello, world!', { - duration: 5000, - position: 'top-right', - clickable: true, - clickClosable: true, - className: 'custom-toast', - render: (message) => , - onClick: (event) => console.log('Toast clicked!'), -}); -``` - -## Live Demo - -Experience React Simple Toasts in action with our [live demo](https://almond-bongbong.github.io/react-simple-toasts/). - ## API ### toast(message, options) -Displays a toast message with the specified message and options. - -#### Main Parameters - -| Parameter | Type | Description | -| ------------------- | --------------------- | -------------------------------------------------------------------------------------------------- | -| `message` | `string`, `ReactNode` | The message to display in the toast. | -| `durationOrOptions` | `number`, `object` | Either the duration for the toast (in milliseconds) or an object containing options for the toast. | - -#### Options Object Properties - -| Property | Type | Description | -| ------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `duration` | `number` | The duration (in milliseconds) for which the toast message will be displayed. Default is `3000`. | -| `className` | `string` | A string of classes to apply to the toast container. | -| `clickable` | `boolean` | A boolean value that determines whether the toast message is clickable. Default is `false`. | -| `clickClosable` | `boolean` | A boolean value that determines whether the toast message can be closed by clicking on it. Default is `false`. | -| `position` | `string` | A string that sets the position of the toast message. Available options are `'bottom-left'`, `'bottom-center'`, `'bottom-right'`, `'top-left'`, `'top-center'`, `'top-right'`, and `'center'`. Default is `'bottom-center'`. | -| `maxVisibleToasts` | `number` | The maximum number of toast messages that can be displayed simultaneously. Default is `null`, which allows an unlimited number of toasts. | -| `render` | `function` | A function that returns a ReactNode to render as the toast message. The function takes a `message` argument, which is the message to display in the toast. Default is `null`. | -| `onClick` | `function` | A function to be called when the toast message is clicked. This function takes an `event` argument, which is the click event. Must be used with `clickable: true`. | -| `onClose` | `function` | A function to be called when the toast message is closed and the closing animation is finished. | -| `onCloseStart` | `function` | A function to be called when the toast message starts closing, right before the closing animation begins. | +Displays a toast message with the specified message and options. Detailed options can be found on our [documentation page](https://almond-bongbong.github.io/react-simple-toasts/api#toast). ### Toast Return Object -When the toast function is called, it returns a control object with methods for managing the toast message currently being displayed. These methods include closing the toast, updating its duration, and updating its message and duration. - -| Method | Description | Version | -| ----------------------------------------------- | -------------------------------------------------------------------------- | ------- | -| `close()` | Closes the currently displayed toast message. | 3.3.0 | -| `updateDuration(newDuration: number)` | Updates the duration of the currently displayed toast message. | 3.5.0 | -| `update(message: ReactNode, duration?: number)` | Updates the message and duration of the currently displayed toast message. | 3.5.0 | +The `toast` function returns a control object with methods to manage the displayed toast. You can find examples of usage on our [documentation page](https://almond-bongbong.github.io/react-simple-toasts/api#toast). -These methods can be invoked at any time to manage the toast message before its duration has elapsed. Here are some examples: - -- Closing the toast message in response to a user interaction, such as a button click: - -```jsx -const myToast = toast('Hello, world!'); -// ... -; -``` +### Configuring Toasts: `createToast` and `toastConfig` -- Updating the duration of the toast message: - -```jsx -const myToast = toast('Hello, world!'); -// ... -; -``` - -- Updating the message and duration of the toast message: - -```jsx -const myToast = toast('Hello, world!'); -// ... -; -``` +The `createToast` and `toastConfig` functions allow for advanced configuration of your toast notifications. Use `createToast` to generate a toast function with specific settings, and `toastConfig` to set default options for all toast messages in your application. See our [documentation page](https://almond-bongbong.github.io/react-simple-toasts/api#toast-config) for more details. -### createToast(options) - -Available from version 3.6.0. - -The `createToast` function creates and returns a new `toast` function instance based on the given options. This allows you to create and manage multiple pre-configured `toast` instances with various options. - -The `options` object contains the following properties: - -| Parameter | Type | Description | -| ------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `duration` | `number` | The duration (in milliseconds) for which the toast message will be displayed. Default is `3000`. | -| `className` | `string` | A string of classes to apply to the toast container. | -| `clickClosable` | `boolean` | A boolean value that determines whether the toast message can be closed by clicking on it. Default is `false`. | -| `position` | `string` | A string that sets the position of the toast message. Available options are `'bottom-left'`, `'bottom-center'`, `'bottom-right'`, `'top-left'`, `'top-center'`, `'top-right'`, and `'center'`. Default is `'bottom-center'`. | -| `maxVisibleToasts` | `number` | The maximum number of toast messages that can be displayed simultaneously. Default is `null`, which allows an unlimited number of toasts. | -| `render` | `function` | A function that returns a ReactNode to render as the toast message. The function takes a `message` argument, which is the message to display in the toast. Default is `null`. | - -`createToast` is similar to `toastConfig`, which sets global default options, but it allows you to create and use toast instances with different configurations for more flexibility. This enables you to apply different options to each toast instance. - -```jsx -import { createToast } from 'react-simple-toasts'; - -const customToast = createToast({ - duration: 5000, - className: 'custom-toast', - clickClosable: true, - position: 'bottom-right', - maxVisibleToasts: 3, - render: (message) => {message}, -}); - -function MyComponent() { - return ( - - ); -} -``` - -### toastConfig(options) - -Sets default options for all toast messages. - -The `options` object contains the following properties: - -| Parameter | Type | Description | -| ------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `duration` | `number` | The duration (in milliseconds) for which the toast message will be displayed. Default is `3000`. | -| `className` | `string` | A string of classes to apply to the toast container. | -| `clickClosable` | `boolean` | A boolean value that determines whether the toast message can be closed by clicking on it. Default is `false`. | -| `position` | `string` | A string that sets the position of the toast message. Available options are `'bottom-left'`, `'bottom-center'`, `'bottom-right'`, `'top-left'`, `'top-center'`, `'top-right'`, and `'center'`. Default is `'bottom-center'`. | -| `maxVisibleToasts` | `number` | The maximum number of toast messages that can be displayed simultaneously. Default is `null`, which allows an unlimited number of toasts. | -| `render` | `function` | A function that returns a ReactNode to render as the toast message. The function takes a `message` argument, which is the message to display in the toast. Default is `null`. | - -`toastConfig` is used to set global default options, which will be applied to all toast instances used throughout your app. However, if you need to create toast instances with different configurations, it is recommended to use `createToast` instead. - -```jsx -// index.js -import { toastConfig } from 'react-simple-toasts'; - -toastConfig({ - duration: 5000, - className: 'custom-toast', - clickClosable: true, - position: 'bottom-right', - maxVisibleToasts: 3, - render: (message) => {message}, -}); -``` - -### clearToasts() - -Removes all currently displayed toast messages. - -This function provides a convenient way to remove all active toast messages at once. It can be useful in situations where you need to clear all toasts, such as when a user logs out or navigates away from a page. +## Contributing -```jsx -import { clearToasts } from 'react-simple-toasts'; +Contributions are always welcome! -function ClearAllToastsButton() { - return ( - - ); -} -``` - -## Contributing +## Support Us -Contributions are always welcome! If you want to contribute to this project. +If you find this library useful, consider giving us a star on [GitHub!](https://github.com/almond-bongbong/react-simple-toasts/stargazers) Your support is greatly appreciated and it helps the project grow. ## License diff --git a/example/package.json b/example/package.json index 7275af6..b25440d 100644 --- a/example/package.json +++ b/example/package.json @@ -13,6 +13,7 @@ "prism-react-renderer": "^2.0.4", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-router-dom": "^6.11.1", "react-simple-toasts": "file:.." }, "devDependencies": { diff --git a/example/src/App.tsx b/example/src/App.tsx deleted file mode 100644 index 791f53d..0000000 --- a/example/src/App.tsx +++ /dev/null @@ -1,468 +0,0 @@ -import { useState } from 'react'; -import toast, { - clearToasts, - createToast, - Toast, - toastConfig, -} from 'react-simple-toasts'; -import CommonHighlighter from './component/CommonHighlighter'; - -const toastA = createToast({ - duration: 3000, -}); - -function App() { - const [infinityToast, setInfinityToast] = useState(null); - const [extendedToast, setExtendedToast] = useState(null); - const [updatedToast, setUpdatedToast] = useState(null); - - return ( -
-
-

react-simple-toasts

-

- React Simple Toasts is a lightweight and versatile toast notification - library for React applications. -

- -
-

Basic Usage

-

- Display a straightforward toast notification with default settings. -

-
- -
- {`import toast from 'react-simple-toasts' - -// ... - -toast('Simple message')`} -
- -
-

Utilizing JSX in Toast Notifications

-

- Leverage JSX to design more intricate and customizable toast - notifications. This example showcases how to include JSX elements - and apply inline styles within the message. -

-
- -
- {`toast(Custom JSX message)`} -
- -
-

Toast Notification Duration

-

- Determine the duration for which the toast notification remains - visible. This example demonstrates how to display a toast - notification for a specific duration. -

-
- -
- - {`toast('This message is displayed for 1 second.', 1000)`} - -
- -
-

Toast Clearing

-

- Clear all toast notifications. This example demonstrates how to - clear all toast notifications. -

-
- - -
- - {`import toast, { clearToasts } from 'react-simple-toasts' - -// ... - -toast('Simple message') -clearToasts()`} - -
- -
-

Toast Notification Duration (Alternative Syntax)

-

- As an alternative, you can use the "duration" option to specify the - display duration. -

-
- -
- - {`toast('This message is displayed for 1 second.', { - duration: 1000, -})`} - -
- -
-

Positioning Toast Notifications

-

- Select the desired position of the toast notification on the screen. - This example demonstrates how to display toast notifications in - various positions. -

- -
- - - -
-
- - - - -
- - {`toast('Top-left positioned toast', { position: 'top-left' }) -toast('Top-center positioned toast', { position: 'top-center' }) -toast('Top-right positioned toast', { position: 'top-right' }) -toast('Bottom-left positioned toast', { position: 'bottom-left' }) -toast('Bottom-center positioned toast', { position: 'bottom-center' }) -toast('Bottom-right positioned toast', { position: 'bottom-right' }) -toast('Center positioned toast', { position: 'center' })`} - -
- -
-

Click-to-Close Toast

-

- Create a toast notification that can be dismissed by clicking on it. - This example demonstrates a toast with the "clickClosable" option - set to true. -

-
- -
- - {`toast('Click to close this toast', { clickClosable: true })`} - -
- -
-

Customize Toast Appearance

-

- Modify the appearance of the toast notification using the "render" - option. In this example, the toast notification will display red - text. -

-
- -
- - {`toast('Red Message', { render: message =>
{message}
})`} -
-
- -
-

Global Configuration

-

- Establish global configurations to apply default settings to all - toast notifications in your application. -

- - {`// index.js -import toast, { toastConfig } from 'react-simple-toasts' - -toastConfig({ - duration: 4000, - className: 'my-toast', - position: 'top-center', - clickClosable: true, - render: message =>
{message}
, -}) - -// ... - -toast('Red Message')`} -
-
- -
-

Max Visible Toasts

-

- Limit the number of toast notifications displayed at the same time. -

-
- -
- - {`toastConfig({ maxVisibleToasts: 3 }); - -// ... - -toast('Toast message');`} - -
- -
-

Apply maxVisibleToasts directly in the toast function.

-
- -
- - {``} - -
- -
-

Control Infinite Toast

-

- In this example, we use the Toast object to display and close a - toast with an infinite duration. -

- -
- - -
- - {`const myToast = toast('Message', Infinity); // Show toast - -myToast.close(); // Close toast`} - -
- -
-

Update Toast Duration

-

- In this example, we use the Toast object's 'updateDuration' method - to update the duration of a toast message. -

- -
- - -
- - {`const myToast = toast('Message', 3000); // Show toast for 3 seconds - -myToast.updateDuration(5000); // Update toast duration to 5 seconds`} - -
- -
-

Update Toast Message and Duration

-

- In this example, we use the Toast object's 'update' method to update - the message and duration of a toast message. -

- -
- - -
- - {`const myToast = toast('Original Message', 3000); // Show toast for 3 seconds - -myToast.update('Updated Message', 5000); // Update toast message and duration`} - -
-
- - -
- ); -} - -export default App; diff --git a/example/src/app.tsx b/example/src/app.tsx new file mode 100644 index 0000000..3636d7d --- /dev/null +++ b/example/src/app.tsx @@ -0,0 +1,37 @@ +import { createBrowserRouter, RouterProvider } from 'react-router-dom'; +import GettingStarted from './page/getting-started'; +import Root from './root'; +import Home from './page/home'; +import Example from './page/example'; +import Api from './page/api'; + +const router = createBrowserRouter([ + { + path: '/', + element: , + children: [ + { + path: '/', + element: , + }, + { + path: '/getting-started', + element: , + }, + { + path: '/api', + element: , + }, + { + path: '/example', + element: , + }, + ], + }, +]); + +function App() { + return ; +} + +export default App; diff --git a/example/src/assets/images/common/github-icon.png b/example/src/assets/images/common/github-icon.png new file mode 100644 index 0000000..9490ffc Binary files /dev/null and b/example/src/assets/images/common/github-icon.png differ diff --git a/example/src/assets/images/common/logo.png b/example/src/assets/images/common/logo.png new file mode 100644 index 0000000..13f209b Binary files /dev/null and b/example/src/assets/images/common/logo.png differ diff --git a/example/src/component/button/button.module.css b/example/src/component/button/button.module.css new file mode 100644 index 0000000..b5faae4 --- /dev/null +++ b/example/src/component/button/button.module.css @@ -0,0 +1,29 @@ +.button { + display: inline-block; + padding: 11px 20px; + outline: 0; + border: 1px solid #ccc; + border-radius: 3px; + background-color: #fff; + box-shadow: 0 1px 1px 0 rgba(100, 100, 100, 0.2); + color: #555; + font-size: 16px; + text-align: center; + cursor: pointer; + white-space: nowrap; +} + +.button:active { + background-color: #fafafa; +} + +.button:disabled { + border: 1px solid #ddd; + background-color: #f5f5f5; + color: #bbb; + cursor: not-allowed; +} + +.button + .button { + margin-left: 8px; +} diff --git a/example/src/component/button/button.tsx b/example/src/component/button/button.tsx new file mode 100644 index 0000000..08e245d --- /dev/null +++ b/example/src/component/button/button.tsx @@ -0,0 +1,10 @@ +import React, { ButtonHTMLAttributes } from 'react'; +import styles from './button.module.css'; + +function Button(props: ButtonHTMLAttributes) { + return ( + + ); +}`} + +
+

+ By default, the toast message is displayed for 3 seconds. Modify the + duration by providing a second argument to the `toast` function: +

+
+ {`toast('Hello, world!', 5000);`} +
+
+

+ By default, the toast message is displayed for 3 seconds. Modify the + duration by providing a second argument to the `toast` function: +

+
+ {`toast('Hello, world!', { + duration: 5000, + position: 'top-right', + clickable: true, + clickClosable: true, + className: 'custom-toast', + render: (message) => , + onClick: (event) => console.log('Toast clicked!'), +});`} +
+
+ +

Main Parameters

+ + + + + + + + + + + + + + + + + + + + +
ParameterTypeDescription
message + string, ReactNode + The message to display in the toast.
durationOrOptions + number, object + + Either the duration for the toast (in milliseconds) or an object + containing options for the toast. +
+
+

Options Object Properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
duration + number + + The duration (in milliseconds) for which the toast message will + be displayed. Default is 3000. +
className + string + A string of classes to apply to the toast container.
clickable + boolean + + A boolean value that determines whether the toast message is + clickable. Default is false. +
clickClosable + boolean + + A boolean value that determines whether the toast message can be + closed by clicking on it. Default is false. +
position + string + + A string that sets the position of the toast message. Available + options are 'bottom-left',{' '} + 'bottom-center', 'bottom-right',{' '} + 'top-left', 'top-center',{' '} + 'top-right', and 'center'. Default is{' '} + 'bottom-center'. +
maxVisibleToasts + number + + The maximum number of toast messages that can be displayed + simultaneously. Default is null, which allows an + unlimited number of toasts. +
render + function + + A function that returns a ReactNode to render as the toast + message. The function takes a message argument, + which is the message to display in the toast. Default is{' '} + null. +
onClick + function + + A function to be called when the toast message is clicked. This + function takes an event argument, which is the + click event. Must be used with clickable: true. +
onClose + function + + A function to be called when the toast message is closed and the + closing animation is finished. +
onCloseStart + function + + A function to be called when the toast message starts closing, + right before the closing animation begins. +
+
+

Toast Return Object

+

+ When you call the toast function, it returns a{' '} + Toast object that you can use to control the displayed + toast message. The Toast object includes the following + methods: +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
MethodDescriptionVersion
+ close() + Closes the currently displayed toast message.3.3.0
+ updateDuration(newDuration: number) + + Updates the duration of the currently displayed toast message. + 3.5.0
+ update(message: ReactNode, duration?: number) + + Updates the message and duration of the currently displayed + toast message. + 3.5.0
+

+ These methods can be invoked at any time to manage the toast message + before its duration has elapsed. +

+
+ {`const myToast = toast('Hello, world!', Infinity); + +// ... + +`} +
+ + +
+

๐Ÿ› ๏ธ Toast Config

+

+ Configuring Toasts: createToast and{' '} + toastConfig +

+

+ The createToast and toastConfig functions + provide methods for configuring and managing toast messages in your + application. Both functions can be used to fine-tune the behavior of + your toast messages, each serving a different purpose. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterTypeDescription
duration + number + + The duration (in milliseconds) for which the toast message will + be displayed. Default is 3000. +
className + string + A string of classes to apply to the toast container.
clickClosable + boolean + + A boolean value that determines whether the toast message can be + closed by clicking on it. Default is false. +
position + string + + A string that sets the position of the toast message. Available + options are 'bottom-left',{' '} + 'bottom-center', 'bottom-right',{' '} + 'top-left', 'top-center',{' '} + 'top-right', and 'center'. Default is{' '} + 'bottom-center'. +
maxVisibleToasts + number + + The maximum number of toast messages that can be displayed + simultaneously. Default is null, which allows an + unlimited number of toasts. +
render + function + + A function that returns a ReactNode to render as the toast + message. The function takes a message argument, + which is the message to display in the toast. Default is{' '} + null. +
+
+ +

createToast(options)

+

+ Introduced in version 3.6.0, the createToast function + generates a new toast function instance based on the given options. + This allows you to create and manage multiple pre-configured toast + instances with different configurations. +

+
+ + {`import { createToast } from 'react-simple-toasts'; + +const customToast = createToast({ + duration: 5000, + className: 'custom-toast', + clickClosable: true, + position: 'bottom-right', + maxVisibleToasts: 3, + render: (message) => {message}, +}); + +function MyComponent() { + return ( + + ); +}`} + +
+
+ +

toastConfig(options)

+

+ The toastConfig function sets default options for all + toast messages in your application. +

+
+ + {`// index.js +import { toastConfig } from 'react-simple-toasts'; + +toastConfig({ + duration: 5000, + className: 'custom-toast', + clickClosable: true, + position: 'bottom-right', + maxVisibleToasts: 3, + render: (message) => {message}, +});`} + +
+
+ +

createToast vs toastConfig

+

+ While both createToast and toastConfig serve + similar purposes, they differ in their usage. toastConfig{' '} + specifies default settings that apply to all toast messages throughout + your application. In contrast, createToast is used to + create distinct toast instances with various configurations. +

+

+ If you need to create toasts with special settings for specific + sections only, it's recommended to use createToast. + However, if you want to maintain consistency across your application, + it's advisable to specify default settings using{' '} + toastConfig. +

+
+ +
+

๐Ÿงน Clearing Toasts

+

clearToasts()

+

+ The clearToasts function is used to dismiss all currently + displayed toast notifications. This can be especially useful in + situations where you want to ensure that all toasts are removed from + the screen, such as navigating away from a page or reacting to + specific user actions. +

+
+

+ Here is an example of how to use the clearToasts{' '} + function: +

+
+ {`import { clearToasts } from 'react-simple-toasts'; + +// ... your other code + +// This will dismiss all current toast notifications +clearToasts();`} +
+
+

+ Note that the clearToasts function does not take any + arguments and does not return a value. It simply removes all toasts + from the screen. +

+
+ + ); +} + +export default Api; diff --git a/example/src/page/api/index.ts b/example/src/page/api/index.ts new file mode 100644 index 0000000..e126924 --- /dev/null +++ b/example/src/page/api/index.ts @@ -0,0 +1 @@ +export { default } from './api'; diff --git a/example/src/page/example/example.module.css b/example/src/page/example/example.module.css new file mode 100644 index 0000000..181f840 --- /dev/null +++ b/example/src/page/example/example.module.css @@ -0,0 +1,15 @@ +.code { + margin-top: 20px; +} + +.area + .area { + margin-top: 40px; +} + +.description { + margin-top: 20px; +} + +.playground { + margin-top: 20px; +} diff --git a/example/src/page/example/example.tsx b/example/src/page/example/example.tsx new file mode 100644 index 0000000..182d7c5 --- /dev/null +++ b/example/src/page/example/example.tsx @@ -0,0 +1,535 @@ +import React, { useState } from 'react'; +import toast, { createToast, Toast, ToastPosition } from 'react-simple-toasts'; +import styles from './example.module.css'; +import CommonHighlighter from '../../component/common-highlighter'; +import Button from '../../component/button'; +import MyMessage from '../../component/example/my-message'; +import { Link } from 'react-router-dom'; + +const toastA = createToast({ + duration: 3000, +}); + +function Example() { + const [position, setPosition] = useState('bottom-center'); + const [infiniteToast, setInfiniteToast] = useState(null); + + return ( +
+
+

๐Ÿ”ฌ Simple Example

+

Here's a simple example of how to use our package:

+
+
+

Basic Usage

+
+ +
+
+ {`import toast from 'react-simple-toasts'; + +export default function App() { + return ( + + ); +}`} +
+
+ +
+

Duration

+ +
+ default: 3000 +
+

+ The duration option, in milliseconds, allows you to + control how long the toast message is displayed. There are two + different ways to set it as shown in the example. +

+
+ +
+
+ {`import toast from 'react-simple-toasts'; + +export default function App() { + return ( + <> + + + + ); +}`} +
+
+ +
+

className

+ +
+ default: undefined +
+

+ The className option allows you to customize the style + of the toast message. You can provide your own CSS class name and + define the styles in your CSS file as shown in the example. +

+
+ +
+
+ {`/* my-style.css */ + +.my-toast > div { + background-color: rgba(255, 255, 255, 0.95); + color: #333; + border-radius: 3px; +}`} +
+
+ {`import toast from 'react-simple-toasts'; +import 'my-style.css'; + +export default function App() { + return ( + + ); +}`} +
+
+ +
+

clickable

+ +
+ default: false +
+ +

+ The clickable option allows you to make the toast + message interactive, meaning it can be clicked. Once{' '} + clickable is set to true, you can provide an{' '} + onClick handler to execute an action when the toast is + clicked, as demonstrated in the example. +

+
+ +
+
+ {`import toast from 'react-simple-toasts'; + +export default function App() { + + const handleClick = () => { + toast('Hello, World!', { + clickable: true, + onClick: () => alert('Clicked!'), + }); + } + + return ( + + ); +}`} +
+
+ +
+

clickClosable

+ +
+ default: false +
+ +

+ The clickClosable prop allows users to dismiss the + toast by clicking on it. When set to true, a click + anywhere on the toast message will close the toast. This provides an + additional, user-friendly way to dismiss toasts, beyond waiting for + them to automatically disappear. +

+ +
+ +
+
+ {`import toast from 'react-simple-toasts'; + +export default function App() { + return ( + + ); +}`} +
+
+ +
+

position

+ +
+ default: bottom-center +
+ +

+ The position prop determines the location on the screen + where the toast will appear. Available positions include "top-left", + "top-center", "top-right", "bottom-left", "bottom-center", + "bottom-right", and "center". This gives you the flexibility to + ensure that the toast doesn't interfere with other important UI + elements. +

+ +
+ + +
+
+ {`import toast, { ToastPosition } from 'react-simple-toasts'; + +export default function App() { + const [position, setPosition] = useState('bottom-center'); + + const handleClick = () => { + toast('Hello, World!', { position }); + } + + return ( + <> + + + + + ); +}`} +
+
+ +
+

maxVisibleToasts

+ +
+ default: undefined +
+ +

+ The maxVisibleToasts prop sets a limit to the number of + toasts that can be displayed on the screen at the same time. If more + toasts are triggered while the limit is reached, they will be queued + and displayed as older toasts disappear. This helps prevent a + scenario where a large number of toasts are displayed + simultaneously, potentially disrupting the user experience. +

+ +
+ +
+
+ {`import toast from 'react-simple-toasts'; + +export default function App() { + return ( + + ); +}`} +
+
+
+ +
+

๐Ÿš€ Advanced Example

+

This is a more advanced example with additional options:

+
+ +
+

Infinite Toast

+ +

+ If you want to create a toast notification that stays on the screen + indefinitely until manually closed, you can pass{' '} + Infinity as the duration. This will create an "infinite + toast". The example below shows how to create an infinite toast and + provide a button for manually closing it. This can be useful in + scenarios where you want to make sure a critical message is not + missed by the user. +

+ +
+ + +
+
+ {`import toast, { Toast } from 'react-simple-toasts'; + +export default function App() { + const [infiniteToast, setInfiniteToast] = useState(null); + + const handleShowClick = () => { + const infiniteToast = toast('Hello, World!', Infinity); + setInfiniteToast(infiniteToast); + }; + + const handleCloseClick = () => { + infiniteToast?.close(); + setInfiniteToast(null); + }; + + return ( + <> + + + + ); +}`} +
+
+ +
+

Updating Toasts in Real-time

+ +

+ The example below demonstrates how to dynamically update the content + of a toast message in real-time. Here, a countdown timer is + implemented to show the remaining lifetime of the toast. It's + updated every 100 milliseconds until the toast is automatically + closed after 5 seconds. The update function of the + toast instance is used to accomplish this. +

+ +
+ +
+
+ {`import toast from 'react-simple-toasts'; + +export default function App() { + const handleClick = () => { + const DURATION = 5000; + const toastCreatedAt = Date.now(); + const updatableToast = toast('Toast will close in 5s', DURATION); + + setInterval(() => { + const remainingTime = Math.max(0, DURATION - (Date.now() - toastCreatedAt)); + updatableToast?.update(\`Toast will close in \${(remainingTime / 1000).toFixed(1)}s\`); + }, 100); + }; + + return ( + + ); +}`} +
+
+
+ +
+

๐ŸŽจ Custom Example

+

Want to get creative? Here's how you can customize our package:

+
+ +
+

render

+
+ default: undefined +
+

+ The render prop allows you to fully customize the + content of the toast. You can return a JSX or a React component to + replace the default toast content. However, note that when this prop + is used, only the base animation applies and all default styles are + discarded. +

+
+ +
+
+ {`import toast from 'react-simple-toasts'; + +export default function App() { + const handleClick = () => { + toast('Hello, World! ๐Ÿ‘‹', { + render: (message) => {message}, + }); + }; + + return ( + + ); +}`} +
+

+ The render option is typically used with{' '} + createToast or toastConfig for creating + more complex and customizable toast notifications. +

+
+

createToast

+
+ {`import { createToast } from 'react-simple-toasts'; + +const myToast = createToast({ + render: (message) => {message}, +}); + +export default function App() { + return ( + + ); +}`} +
+
+

toastConfig

+
+ {`import toast, { toastConfig } from 'react-simple-toasts'; + +toastConfig({ + render: (message) => {message}, +}); + +export default function App() { + return ( + + ); +}`} +
+

+ For the differences between createToast and{' '} + toastConfig, please refer to the{' '} + API documentation. +

+
+
+
+ ); +} + +export default Example; diff --git a/example/src/page/example/index.ts b/example/src/page/example/index.ts new file mode 100644 index 0000000..f46b838 --- /dev/null +++ b/example/src/page/example/index.ts @@ -0,0 +1 @@ +export { default } from './example'; diff --git a/example/src/page/getting-started/getting-started.module.css b/example/src/page/getting-started/getting-started.module.css new file mode 100644 index 0000000..e69de29 diff --git a/example/src/page/getting-started/getting-started.tsx b/example/src/page/getting-started/getting-started.tsx new file mode 100644 index 0000000..30ba5f3 --- /dev/null +++ b/example/src/page/getting-started/getting-started.tsx @@ -0,0 +1,50 @@ +import React from 'react'; +import CommonHighlighter from '../../component/common-highlighter'; + +function GettingStarted() { + return ( +
+
+

๐Ÿ“ฆ Installation

+

+ To get started with React Simple Toasts, install the package using npm + or yarn: +

+
+ {`// with npm +npm install react-simple-toasts + +// with yarn +yarn add react-simple-toasts`} +
+
+

๐Ÿ›  Usage

+

Here is a simple example of how to use React Simple Toasts:

+
+ + {`import React from 'react'; +import toast from 'react-simple-toasts'; + +function App() { + return ( +
+ +
+ ); +} + +export default App;`} +
+
+

๐ŸŒŸ Benefits of using React Simple Toasts:

+
    +
  • No need for Provider or any wrapper components.
  • +
+
+
+ ); +} + +export default GettingStarted; diff --git a/example/src/page/getting-started/index.ts b/example/src/page/getting-started/index.ts new file mode 100644 index 0000000..c1aeb2b --- /dev/null +++ b/example/src/page/getting-started/index.ts @@ -0,0 +1 @@ +export { default } from './getting-started'; diff --git a/example/src/page/home/home.module.css b/example/src/page/home/home.module.css new file mode 100644 index 0000000..10af336 --- /dev/null +++ b/example/src/page/home/home.module.css @@ -0,0 +1,8 @@ +.features { + padding-left: 20px; + list-style: disc; +} + +.features li + li { + margin-top: 10px; +} diff --git a/example/src/page/home/home.tsx b/example/src/page/home/home.tsx new file mode 100644 index 0000000..cc285b5 --- /dev/null +++ b/example/src/page/home/home.tsx @@ -0,0 +1,82 @@ +import React from 'react'; +import styles from './home.module.css'; +import toast from 'react-simple-toasts'; +import Button from '../../component/button'; + +function Home() { + return ( +
+
+

๐Ÿ” Overview

+

+ React Simple Toasts is a lightweight, easy-to-use library for creating + toast notifications in your React applications. +

+
+ +
+ +
+

๐Ÿ”‘ Key Features

+
    +
  • + Ease of use: With a simple installation process and an + intuitive API, you can get started with the library in no time. +
  • +
  • + Highly customizable: You can control various aspects of your + toast messages, from their appearance and duration to their behavior + upon user interaction. +
  • +
  • + Custom rendering: The library supports custom rendering, + allowing you to tailor the look of your toast messages to match your + application's branding. +
  • +
  • + Positioning: The library allows you to position your toasts + at any corner or center of the viewport, offering a high level of + control over where your messages appear. +
  • +
  • + Browser compatibility: The library includes utility functions + to ensure that it works seamlessly across different browsers. +
  • +
  • + Interactive: The library allows toasts to be clickable and to + close on click if desired, enabling user interaction. +
  • +
  • + Multiple toasts management: It provides functionality to + manage multiple toasts by controlling the maximum number of visible + toasts at a time. +
  • +
+
+ +
+

๐Ÿ’– Support Us

+

+ If you find this library useful, consider giving us a star on{' '} + + GitHub + + ! Your support is greatly appreciated and it helps the project grow. +

+
+ +
+

โš–๏ธ License

+

This project is licensed under the terms of the MIT license.

+
+
+ ); +} + +export default Home; diff --git a/example/src/page/home/index.ts b/example/src/page/home/index.ts new file mode 100644 index 0000000..2fdb147 --- /dev/null +++ b/example/src/page/home/index.ts @@ -0,0 +1 @@ +export { default } from './home'; diff --git a/example/src/root.tsx b/example/src/root.tsx new file mode 100644 index 0000000..eb8ef70 --- /dev/null +++ b/example/src/root.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import Layout from './component/layout'; +import { Outlet } from 'react-router-dom'; + +function Root() { + return ( + + + + ); +} + +export default Root; diff --git a/example/src/type/utils.ts b/example/src/type/utils.ts new file mode 100644 index 0000000..3fd6e6d --- /dev/null +++ b/example/src/type/utils.ts @@ -0,0 +1 @@ +export type AtLeast = Partial & Pick diff --git a/example/src/util/debounce.ts b/example/src/util/debounce.ts new file mode 100644 index 0000000..3a43e97 --- /dev/null +++ b/example/src/util/debounce.ts @@ -0,0 +1,53 @@ +/* eslint-disable-next-line @typescript-eslint/no-explicit-any */ +export type Procedure = (...args: any[]) => void; + +export type Options = { + isImmediate: boolean; +}; + +export interface DebouncedFunction { + (this: ThisParameterType, ...args: Parameters): void; + cancel: () => void; +} + +export function debounce( + func: F, + waitMilliseconds = 50, + options: Options = { + isImmediate: false, + }, +): DebouncedFunction { + let timeoutId: ReturnType | undefined; + + const debouncedFunction = function ( + this: ThisParameterType, + ...args: Parameters + ) { + const doLater = function () { + timeoutId = undefined; + if (!options.isImmediate) { + func(...args); + } + }; + + const shouldCallNow = options.isImmediate && timeoutId === undefined; + + if (timeoutId !== undefined) { + clearTimeout(timeoutId); + } + + timeoutId = setTimeout(doLater, waitMilliseconds); + + if (shouldCallNow) { + func(...args); + } + }; + + debouncedFunction.cancel = function () { + if (timeoutId !== undefined) { + clearTimeout(timeoutId); + } + }; + + return debouncedFunction; +} diff --git a/example/yarn.lock b/example/yarn.lock index 4b5c2f9..c9cd025 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -184,6 +184,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@remix-run/router@1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.6.1.tgz#3a3a408481a3796f45223a549c2571517bc8af2d" + integrity sha512-YUkWj+xs0oOzBe74OgErsuR3wVn+efrFhXBWrit50kOiED+pvQe2r6MWY0iJMQU/mSVKxvNzL4ZaYvjdX+G7ZA== + "@swc/core-darwin-arm64@1.3.56": version "1.3.56" resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.56.tgz#a846f7fdbc274aa7d299568031dde025d44a3b4c" @@ -1069,6 +1074,21 @@ react-dom@^18.2.0: loose-envify "^1.1.0" scheduler "^0.23.0" +react-router-dom@^6.11.1: + version "6.11.1" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.11.1.tgz#af226bae950deb437208a606a47cf5c2d72c55dc" + integrity sha512-dPC2MhoPeTQ1YUOt5uIK376SMNWbwUxYRWk2ZmTT4fZfwlOvabF8uduRKKJIyfkCZvMgiF0GSCQckmkGGijIrg== + dependencies: + "@remix-run/router" "1.6.1" + react-router "6.11.1" + +react-router@6.11.1: + version "6.11.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.11.1.tgz#6e58458c03e16834dda2b433c6adb9e7c2b1d7a8" + integrity sha512-OZINSdjJ2WgvAi7hgNLazrEV8SGn6xrKA+MkJe9wVDMZ3zQ6fdJocUjpCUCI0cNrelWjcvon0S/QK/j0NzL3KA== + dependencies: + "@remix-run/router" "1.6.1" + "react-simple-toasts@file:..": version "3.6.0" diff --git a/package.json b/package.json index bf89e77..a41b88e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-simple-toasts", - "version": "3.6.0", + "version": "3.6.1", "description": "React Simple Toasts is a simple and easy-to-use toast message popup for React.", "author": "almond-bongbong", "homepage": "https://github.com/almond-bongbong/react-simple-toasts", diff --git a/src/index.tsx b/src/index.tsx index 8f2cc01..ded2fe6 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -12,10 +12,10 @@ import styles from './style.css'; import { addRootElement, createElement } from './lib/generateElement'; import { render as reactRender } from './lib/react-render'; import { createId, isBrowser } from './lib/utils'; -import { SET_TIMEOUT_MAX, ToastPosition } from './lib/constants'; +import { SET_TIMEOUT_MAX, ToastPosition as Position } from './lib/constants'; type ClickHandler = (e: SyntheticEvent) => void | Promise; -type Position = (typeof ToastPosition)[keyof typeof ToastPosition]; +export type ToastPosition = (typeof Position)[keyof typeof Position]; export interface ToastOptions { /** @@ -26,7 +26,7 @@ export interface ToastOptions { className?: string; clickable?: boolean; clickClosable?: boolean; - position?: Position; + position?: ToastPosition; maxVisibleToasts?: number | null; render?: ((message: ReactNode) => ReactNode) | null; onClick?: ClickHandler; @@ -64,7 +64,7 @@ export interface Toast { let toastComponentList: { id: number; message: ReactNode; - position: Position; + position: ToastPosition; component: ReactElement; isExit?: boolean; }[] = []; @@ -90,12 +90,12 @@ const defaultOptions: Required = { maxVisibleToasts: null, }; -const isValidPosition = (position: Position): boolean => { - const positionList = Object.values(ToastPosition); +const isValidPosition = (position: ToastPosition): boolean => { + const positionList = Object.values(Position); if (!positionList.includes(position)) { throw new Error( `Invalid position value. Expected one of ${Object.values( - ToastPosition, + Position, ).join(', ')} but got ${position}`, ); } @@ -132,7 +132,7 @@ const renderDOM = () => { const toastContainer = document.getElementById(styles['toast_container']); if (!toastContainer) return; - const defaultToastList = Object.values(ToastPosition).reduce( + const defaultToastList = Object.values(Position).reduce( (acc, position) => ({ ...acc, [position]: [],