feat: Passwordless cross-device authentication

- Arkitektur: docs/auth/passwordless-architecture.md
- Backend: iom/quixzoom-auth-service/ (FastAPI + Redis)
- Webb: quixzoom-market-pages/se/login/ (QR-kod + polling)
- App: iom/quixzoom-app/src/features/auth/ (push + deep links)

Flöde: QR-kod → app-godkännande → webb-inloggad
This commit is contained in:
Bernt
2026-07-07 07:11:50 +00:00
parent 4aa984ad74
commit 6989a98d75
61843 changed files with 5491611 additions and 872231 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Fadi Khadra
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+112
View File
@@ -0,0 +1,112 @@
# React-Toastify
[![Financial Contributors on Open Collective](https://opencollective.com/react-toastify/all/badge.svg?label=financial+contributors)](https://opencollective.com/react-toastify) ![React-toastify CI](https://github.com/fkhadra/react-toastify/workflows/React-toastify%20CI/badge.svg)
![npm](https://img.shields.io/npm/dm/react-toastify.svg?label=%E2%8F%ACdownloads&style=for-the-badge)
![npm](https://img.shields.io/npm/v/react-toastify.svg?style=for-the-badge)
![NPM](https://img.shields.io/npm/l/react-toastify.svg?label=%F0%9F%93%9Clicense&style=for-the-badge)
![Coveralls github](https://img.shields.io/coveralls/github/fkhadra/react-toastify.svg?label=%E2%9B%B1coverage&style=for-the-badge)
![React toastify](https://user-images.githubusercontent.com/5574267/35336500-e58f35b6-0118-11e8-800b-2da6594fc700.gif "React toastify")
🎉 React-Toastify allows you to add notifications to your app with ease. No more nonsense!
## Installation
```
$ npm install --save react-toastify
$ yarn add react-toastify
```
## Features
- Easy to set up for real, you can make it work in less than 10sec!
- Super easy to customize
- RTL support
- Swipe to close 👌
- Can choose swipe direction
- Super easy to use an animation of your choice. Works well with animate.css for example
- Can display a react component inside the toast!
- Has ```onOpen``` and ```onClose``` hooks. Both can access the props passed to the react component rendered inside the toast
- Can remove a toast programmatically
- Define behavior per toast
- Pause toast when the window loses focus 👁
- Fancy progress bar to display the remaining time
- Possibility to update a toast
- You can control the progress bar a la `nprogress` 😲
- You can limit the number of toast displayed at the same time
- Dark mode 🌒
- And much more !
## The gist
```jsx
import React from 'react';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
function App(){
const notify = () => toast("Wow so easy!");
return (
<div>
<button onClick={notify}>Notify!</button>
<ToastContainer />
</div>
);
}
```
## Demo
[A demo is worth a thousand words](https://fkhadra.github.io/react-toastify/introduction)
## Documentation
Check the [documentation](https://fkhadra.github.io/react-toastify/introduction) to get you started!
## Contribute
Show your ❤️ and support by giving a ⭐. Any suggestions are welcome! Take a look at the contributing guide.
You can also find me on [reactiflux](https://www.reactiflux.com/). My pseudo is Fadi.
## Contributors
### Code Contributors
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
<a href="https://github.com/fkhadra/react-toastify/graphs/contributors"><img src="https://opencollective.com/react-toastify/contributors.svg?width=890&button=false" /></a>
### Financial Contributors
Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/react-toastify/contribute)]
#### Individuals
<a href="https://opencollective.com/react-toastify"><img src="https://opencollective.com/react-toastify/individuals.svg?width=890"></a>
#### Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/react-toastify/contribute)]
<a href="https://opencollective.com/react-toastify/organization/0/website"><img src="https://opencollective.com/react-toastify/organization/0/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/1/website"><img src="https://opencollective.com/react-toastify/organization/1/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/2/website"><img src="https://opencollective.com/react-toastify/organization/2/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/3/website"><img src="https://opencollective.com/react-toastify/organization/3/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/4/website"><img src="https://opencollective.com/react-toastify/organization/4/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/5/website"><img src="https://opencollective.com/react-toastify/organization/5/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/6/website"><img src="https://opencollective.com/react-toastify/organization/6/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/7/website"><img src="https://opencollective.com/react-toastify/organization/7/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/8/website"><img src="https://opencollective.com/react-toastify/organization/8/avatar.svg"></a>
<a href="https://opencollective.com/react-toastify/organization/9/website"><img src="https://opencollective.com/react-toastify/organization/9/avatar.svg"></a>
## Release Notes
You can find the release note for the latest release [here](https://github.com/fkhadra/react-toastify/releases/latest)
You can browse them all [here](https://github.com/fkhadra/react-toastify/releases)
## License
Licensed under MIT
+506
View File
@@ -0,0 +1,506 @@
.Toastify__toast-container {
z-index: 9999;
-webkit-transform: translate3d(0, 0, 9999px);
position: fixed;
padding: 4px;
width: 320px;
box-sizing: border-box;
color: #fff;
}
.Toastify__toast-container--top-left {
top: 1em;
left: 1em;
}
.Toastify__toast-container--top-center {
top: 1em;
left: 50%;
transform: translateX(-50%);
}
.Toastify__toast-container--top-right {
top: 1em;
right: 1em;
}
.Toastify__toast-container--bottom-left {
bottom: 1em;
left: 1em;
}
.Toastify__toast-container--bottom-center {
bottom: 1em;
left: 50%;
transform: translateX(-50%);
}
.Toastify__toast-container--bottom-right {
bottom: 1em;
right: 1em;
}
@media only screen and (max-width : 480px) {
.Toastify__toast-container {
width: 100vw;
padding: 0;
left: 0;
margin: 0;
}
.Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .Toastify__toast-container--top-right {
top: 0;
transform: translateX(0);
}
.Toastify__toast-container--bottom-left, .Toastify__toast-container--bottom-center, .Toastify__toast-container--bottom-right {
bottom: 0;
transform: translateX(0);
}
.Toastify__toast-container--rtl {
right: 0;
left: initial;
}
}
.Toastify__toast {
position: relative;
min-height: 64px;
box-sizing: border-box;
margin-bottom: 1rem;
padding: 8px;
border-radius: 4px;
box-shadow: 0 1px 10px 0 rgba(0, 0, 0, 0.1), 0 2px 15px 0 rgba(0, 0, 0, 0.05);
display: -ms-flexbox;
display: flex;
-ms-flex-pack: justify;
justify-content: space-between;
max-height: 800px;
overflow: hidden;
font-family: sans-serif;
cursor: pointer;
direction: ltr;
}
.Toastify__toast--rtl {
direction: rtl;
}
.Toastify__toast--dark {
background: #121212;
color: #fff;
}
.Toastify__toast--default {
background: #fff;
color: #aaa;
}
.Toastify__toast--info {
background: #3498db;
}
.Toastify__toast--success {
background: #07bc0c;
}
.Toastify__toast--warning {
background: #f1c40f;
}
.Toastify__toast--error {
background: #e74c3c;
}
.Toastify__toast-body {
margin: auto 0;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
padding: 6px;
}
.Toastify--animate {
animation-fill-mode: both;
animation-duration: 0.7s;
}
@media only screen and (max-width : 480px) {
.Toastify__toast {
margin-bottom: 0;
border-radius: 0;
}
}
.Toastify__close-button {
color: #fff;
background: transparent;
outline: none;
border: none;
padding: 0;
cursor: pointer;
opacity: 0.7;
transition: 0.3s ease;
-ms-flex-item-align: start;
align-self: flex-start;
}
.Toastify__close-button--default {
color: #000;
opacity: 0.3;
}
.Toastify__close-button > svg {
fill: currentColor;
height: 16px;
width: 14px;
}
.Toastify__close-button:hover, .Toastify__close-button:focus {
opacity: 1;
}
@keyframes Toastify__trackProgress {
0% {
transform: scaleX(1);
}
100% {
transform: scaleX(0);
}
}
.Toastify__progress-bar {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 5px;
z-index: 9999;
opacity: 0.7;
background-color: rgba(255, 255, 255, 0.7);
transform-origin: left;
}
.Toastify__progress-bar--animated {
animation: Toastify__trackProgress linear 1 forwards;
}
.Toastify__progress-bar--controlled {
transition: transform 0.2s;
}
.Toastify__progress-bar--rtl {
right: 0;
left: initial;
transform-origin: right;
}
.Toastify__progress-bar--default {
background: linear-gradient(to right, #4cd964, #5ac8fa, #007aff, #34aadc, #5856d6, #ff2d55);
}
.Toastify__progress-bar--dark {
background: #bb86fc;
}
@keyframes Toastify__bounceInRight {
from, 60%, 75%, 90%, to {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
from {
opacity: 0;
transform: translate3d(3000px, 0, 0);
}
60% {
opacity: 1;
transform: translate3d(-25px, 0, 0);
}
75% {
transform: translate3d(10px, 0, 0);
}
90% {
transform: translate3d(-5px, 0, 0);
}
to {
transform: none;
}
}
@keyframes Toastify__bounceOutRight {
20% {
opacity: 1;
transform: translate3d(-20px, 0, 0);
}
to {
opacity: 0;
transform: translate3d(2000px, 0, 0);
}
}
@keyframes Toastify__bounceInLeft {
from, 60%, 75%, 90%, to {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
0% {
opacity: 0;
transform: translate3d(-3000px, 0, 0);
}
60% {
opacity: 1;
transform: translate3d(25px, 0, 0);
}
75% {
transform: translate3d(-10px, 0, 0);
}
90% {
transform: translate3d(5px, 0, 0);
}
to {
transform: none;
}
}
@keyframes Toastify__bounceOutLeft {
20% {
opacity: 1;
transform: translate3d(20px, 0, 0);
}
to {
opacity: 0;
transform: translate3d(-2000px, 0, 0);
}
}
@keyframes Toastify__bounceInUp {
from, 60%, 75%, 90%, to {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
from {
opacity: 0;
transform: translate3d(0, 3000px, 0);
}
60% {
opacity: 1;
transform: translate3d(0, -20px, 0);
}
75% {
transform: translate3d(0, 10px, 0);
}
90% {
transform: translate3d(0, -5px, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
@keyframes Toastify__bounceOutUp {
20% {
transform: translate3d(0, -10px, 0);
}
40%, 45% {
opacity: 1;
transform: translate3d(0, 20px, 0);
}
to {
opacity: 0;
transform: translate3d(0, -2000px, 0);
}
}
@keyframes Toastify__bounceInDown {
from, 60%, 75%, 90%, to {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
0% {
opacity: 0;
transform: translate3d(0, -3000px, 0);
}
60% {
opacity: 1;
transform: translate3d(0, 25px, 0);
}
75% {
transform: translate3d(0, -10px, 0);
}
90% {
transform: translate3d(0, 5px, 0);
}
to {
transform: none;
}
}
@keyframes Toastify__bounceOutDown {
20% {
transform: translate3d(0, 10px, 0);
}
40%, 45% {
opacity: 1;
transform: translate3d(0, -20px, 0);
}
to {
opacity: 0;
transform: translate3d(0, 2000px, 0);
}
}
.Toastify__bounce-enter--top-left, .Toastify__bounce-enter--bottom-left {
animation-name: Toastify__bounceInLeft;
}
.Toastify__bounce-enter--top-right, .Toastify__bounce-enter--bottom-right {
animation-name: Toastify__bounceInRight;
}
.Toastify__bounce-enter--top-center {
animation-name: Toastify__bounceInDown;
}
.Toastify__bounce-enter--bottom-center {
animation-name: Toastify__bounceInUp;
}
.Toastify__bounce-exit--top-left, .Toastify__bounce-exit--bottom-left {
animation-name: Toastify__bounceOutLeft;
}
.Toastify__bounce-exit--top-right, .Toastify__bounce-exit--bottom-right {
animation-name: Toastify__bounceOutRight;
}
.Toastify__bounce-exit--top-center {
animation-name: Toastify__bounceOutUp;
}
.Toastify__bounce-exit--bottom-center {
animation-name: Toastify__bounceOutDown;
}
@keyframes Toastify__zoomIn {
from {
opacity: 0;
transform: scale3d(0.3, 0.3, 0.3);
}
50% {
opacity: 1;
}
}
@keyframes Toastify__zoomOut {
from {
opacity: 1;
}
50% {
opacity: 0;
transform: scale3d(0.3, 0.3, 0.3);
}
to {
opacity: 0;
}
}
.Toastify__zoom-enter {
animation-name: Toastify__zoomIn;
}
.Toastify__zoom-exit {
animation-name: Toastify__zoomOut;
}
@keyframes Toastify__flipIn {
from {
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
animation-timing-function: ease-in;
opacity: 0;
}
40% {
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
animation-timing-function: ease-in;
}
60% {
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
opacity: 1;
}
80% {
transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
}
to {
transform: perspective(400px);
}
}
@keyframes Toastify__flipOut {
from {
transform: perspective(400px);
}
30% {
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
opacity: 1;
}
to {
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
opacity: 0;
}
}
.Toastify__flip-enter {
animation-name: Toastify__flipIn;
}
.Toastify__flip-exit {
animation-name: Toastify__flipOut;
}
@keyframes Toastify__slideInRight {
from {
transform: translate3d(110%, 0, 0);
visibility: visible;
}
to {
transform: translate3d(0, 0, 0);
}
}
@keyframes Toastify__slideInLeft {
from {
transform: translate3d(-110%, 0, 0);
visibility: visible;
}
to {
transform: translate3d(0, 0, 0);
}
}
@keyframes Toastify__slideInUp {
from {
transform: translate3d(0, 110%, 0);
visibility: visible;
}
to {
transform: translate3d(0, 0, 0);
}
}
@keyframes Toastify__slideInDown {
from {
transform: translate3d(0, -110%, 0);
visibility: visible;
}
to {
transform: translate3d(0, 0, 0);
}
}
@keyframes Toastify__slideOutRight {
from {
transform: translate3d(0, 0, 0);
}
to {
visibility: hidden;
transform: translate3d(110%, 0, 0);
}
}
@keyframes Toastify__slideOutLeft {
from {
transform: translate3d(0, 0, 0);
}
to {
visibility: hidden;
transform: translate3d(-110%, 0, 0);
}
}
@keyframes Toastify__slideOutDown {
from {
transform: translate3d(0, 0, 0);
}
to {
visibility: hidden;
transform: translate3d(0, 500px, 0);
}
}
@keyframes Toastify__slideOutUp {
from {
transform: translate3d(0, 0, 0);
}
to {
visibility: hidden;
transform: translate3d(0, -500px, 0);
}
}
.Toastify__slide-enter--top-left, .Toastify__slide-enter--bottom-left {
animation-name: Toastify__slideInLeft;
}
.Toastify__slide-enter--top-right, .Toastify__slide-enter--bottom-right {
animation-name: Toastify__slideInRight;
}
.Toastify__slide-enter--top-center {
animation-name: Toastify__slideInDown;
}
.Toastify__slide-enter--bottom-center {
animation-name: Toastify__slideInUp;
}
.Toastify__slide-exit--top-left, .Toastify__slide-exit--bottom-left {
animation-name: Toastify__slideOutLeft;
}
.Toastify__slide-exit--top-right, .Toastify__slide-exit--bottom-right {
animation-name: Toastify__slideOutRight;
}
.Toastify__slide-exit--top-center {
animation-name: Toastify__slideOutUp;
}
.Toastify__slide-exit--bottom-center {
animation-name: Toastify__slideOutDown;
}
/*# sourceMappingURL=ReactToastify.css.map */
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../scss/_toastContainer.scss","../scss/_variables.scss","ReactToastify.css","../scss/_toast.scss","../scss/_closeButton.scss","../scss/_progressBar.scss","../scss/animations/_bounce.scss","../scss/animations/_zoom.scss","../scss/animations/_flip.scss","../scss/animations/_slide.scss"],"names":[],"mappings":"AAAA;EACI,aCmBS;EDlBT,4CAAA;EACA,eAAA;EACA,YAAA;EACA,YCJa;EDKb,sBAAA;EACA,WAAA;AECJ;AFAI;EACI,QAAA;EACA,SAAA;AEER;AFAI;EACI,QAAA;EACA,SAAA;EACA,2BAAA;AEER;AFAI;EACI,QAAA;EACA,UAAA;AEER;AFAI;EACI,WAAA;EACA,SAAA;AEER;AFAI;EACI,WAAA;EACA,SAAA;EACA,2BAAA;AEER;AFAI;EACI,WAAA;EACA,UAAA;AEER;;AFEA;EACI;IACI,YAAA;IACA,UAAA;IACA,OAAA;IACA,SAAA;EECN;EFAM;IAGI,MAAA;IACA,wBAAA;EEAV;EFEM;IAGI,SAAA;IACA,wBAAA;EEFV;EFIM;IACE,QAAA;IACA,aAAA;EEFR;AACF;ACvDA;EACE,kBAAA;EACA,gBFCoB;EEApB,sBAAA;EACA,mBAAA;EACA,YAAA;EACA,kBAAA;EACA,6EAAA;EACA,oBAAA;EAAA,aAAA;EACA,sBAAA;MAAA,8BAAA;EACA,iBFNoB;EEOpB,gBAAA;EACA,uBFOe;EENf,eAAA;EACA,cAAA;ADyDF;ACxDE;EACE,cAAA;AD0DJ;ACxDE;EACE,mBFZY;EEaZ,WFNiB;ACgErB;ACxDE;EACE,gBFjBe;EEkBf,WFXoB;ACqExB;ACxDE;EACE,mBFnBY;AC6EhB;ACxDE;EACE,mBFrBe;AC+EnB;ACxDE;EACE,mBFvBe;ACiFnB;ACxDE;EACE,mBFzBa;ACmFjB;ACxDE;EACE,cAAA;EACA,kBAAA;MAAA,cAAA;EACA,YAAA;AD0DJ;;ACtDA;EACE,yBAAA;EACA,wBAAA;ADyDF;;ACtDA;EACE;IACE,gBAAA;IACA,gBAAA;EDyDF;AACF;AE/GA;EACE,WAAA;EACA,uBAAA;EACA,aAAA;EACA,YAAA;EACA,UAAA;EACA,eAAA;EACA,YAAA;EACA,qBAAA;EACA,0BAAA;MAAA,sBAAA;AFiHF;AE/GE;EACE,WAAA;EACA,YAAA;AFiHJ;AE9GE;EACE,kBAAA;EACA,YAAA;EACA,WAAA;AFgHJ;AE7GE;EACE,UAAA;AF+GJ;;AGtIA;EACE;IACE,oBAAA;EHyIF;EGvIA;IACE,oBAAA;EHyIF;AACF;AGtIA;EACE,kBAAA;EACA,SAAA;EACA,OAAA;EACA,WAAA;EACA,WAAA;EACA,aJKW;EIJX,YAAA;EACA,0CAAA;EACA,sBAAA;AHwIF;AGtIE;EACE,oDAAA;AHwIJ;AGrIE;EACE,0BAAA;AHuIJ;AGpIE;EACE,QAAA;EACA,aAAA;EACA,uBAAA;AHsIJ;AGnIE;EACE,2FJnBwB;ACwJ5B;AGlIE;EACE,mBJtBqB;AC0JzB;AIvKA;EACI;IAJA,8DAAA;EJ8KF;EInKE;IACI,UAAA;IACA,oCAAA;EJqKN;EInKE;IACI,UAAA;IACA,mCAAA;EJqKN;EInKE;IACI,kCAAA;EJqKN;EInKE;IACI,kCAAA;EJqKN;EInKE;IACI,eAAA;EJqKN;AACF;AIlKA;EACI;IACI,UAAA;IACA,mCAAA;EJoKN;EIlKE;IACI,UAAA;IACA,oCAAA;EJoKN;AACF;AIjKA;EACI;IA1CA,8DAAA;EJ8MF;EI7JE;IACI,UAAA;IACA,qCAAA;EJ+JN;EI7JE;IACI,UAAA;IACA,kCAAA;EJ+JN;EI7JE;IACI,mCAAA;EJ+JN;EI7JE;IACI,iCAAA;EJ+JN;EI7JE;IACI,eAAA;EJ+JN;AACF;AI5JA;EACI;IACI,UAAA;IACA,kCAAA;EJ8JN;EI5JE;IACI,UAAA;IACA,qCAAA;EJ8JN;AACF;AI3JA;EACI;IAhFA,8DAAA;EJ8OF;EIvJE;IACI,UAAA;IACA,oCAAA;EJyJN;EIvJE;IACI,UAAA;IACA,mCAAA;EJyJN;EIvJE;IACI,kCAAA;EJyJN;EIvJE;IACI,kCAAA;EJyJN;EIvJE;IACI,+BAAA;EJyJN;AACF;AItJA;EACI;IACI,mCAAA;EJwJN;EItJE;IAEI,UAAA;IACA,kCAAA;EJuJN;EIrJE;IACI,UAAA;IACA,qCAAA;EJuJN;AACF;AIpJA;EACI;IA1HA,8DAAA;EJiRF;EIhJE;IACI,UAAA;IACA,qCAAA;EJkJN;EIhJE;IACI,UAAA;IACA,kCAAA;EJkJN;EIhJE;IACI,mCAAA;EJkJN;EIhJE;IACI,iCAAA;EJkJN;EIhJE;IACI,eAAA;EJkJN;AACF;AI/IA;EACI;IACI,kCAAA;EJiJN;EI/IE;IAEI,UAAA;IACA,mCAAA;EJgJN;EI9IE;IACI,UAAA;IACA,oCAAA;EJgJN;AACF;AI5II;EAEI,sCAAA;AJ6IR;AI3II;EAEI,uCAAA;AJ4IR;AI1II;EACI,sCAAA;AJ4IR;AI1II;EACI,oCAAA;AJ4IR;;AIvII;EAEI,uCAAA;AJyIR;AIvII;EAEI,wCAAA;AJwIR;AItII;EACI,qCAAA;AJwIR;AItII;EACI,uCAAA;AJwIR;;AK1UA;EACI;IACI,UAAA;IACA,iCAAA;EL6UN;EK3UE;IACI,UAAA;EL6UN;AACF;AK1UA;EACI;IACI,UAAA;EL4UN;EK1UE;IACI,UAAA;IACA,iCAAA;EL4UN;EK1UE;IACI,UAAA;EL4UN;AACF;AKzUA;EACI,gCAAA;AL2UJ;;AKxUA;EACI,iCAAA;AL2UJ;;AMvWA;EACI;IACI,sDAAA;IACA,kCAAA;IACA,UAAA;EN0WN;EMxWE;IACI,uDAAA;IACA,kCAAA;EN0WN;EMxWE;IACI,sDAAA;IACA,UAAA;EN0WN;EMxWE;IACI,sDAAA;EN0WN;EMxWE;IACI,6BAAA;EN0WN;AACF;AMvWA;EACI;IACI,6BAAA;ENyWN;EMvWE;IACI,uDAAA;IACA,UAAA;ENyWN;EMvWE;IACI,sDAAA;IACA,UAAA;ENyWN;AACF;AMtWA;EACI,gCAAA;ANwWJ;;AMrWA;EACI,iCAAA;ANwWJ;;AO7YA;EACI;IACI,kCAAA;IACA,mBAAA;EPgZN;EO9YE;IARA,+BAAA;EPyZF;AACF;AO7YA;EACI;IACI,mCAAA;IACA,mBAAA;EP+YN;EO7YE;IAlBA,+BAAA;EPkaF;AACF;AO5YA;EACI;IACI,kCAAA;IACA,mBAAA;EP8YN;EO5YE;IA5BA,+BAAA;EP2aF;AACF;AO3YA;EACI;IACI,mCAAA;IACA,mBAAA;EP6YN;EO3YE;IAtCA,+BAAA;EPobF;AACF;AO1YA;EACI;IA5CA,+BAAA;EPybF;EO1YE;IACI,kBAAA;IACA,kCAAA;EP4YN;AACF;AOzYA;EACI;IAtDA,+BAAA;EPkcF;EOzYE;IACI,kBAAA;IACA,mCAAA;EP2YN;AACF;AOxYA;EACI;IAhEA,+BAAA;EP2cF;EOxYE;IACI,kBAAA;IACA,mCAAA;EP0YN;AACF;AOvYA;EACI;IA1EA,+BAAA;EPodF;EOvYE;IACI,kBAAA;IACA,oCAAA;EPyYN;AACF;AOrYI;EAEI,qCAAA;APsYR;AOpYI;EAEI,sCAAA;APqYR;AOnYI;EACI,qCAAA;APqYR;AOnYI;EACI,mCAAA;APqYR;;AOhYI;EAEI,sCAAA;APkYR;AOhYI;EAEI,uCAAA;APiYR;AO/XI;EACI,oCAAA;APiYR;AO/XI;EACI,sCAAA;APiYR","file":"ReactToastify.css"}
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
@keyframes Toastify__trackProgress{0%{transform:scaleX(1)}to{transform:scaleX(0)}}.Toastify__progress-bar{animation:Toastify__trackProgress linear 1 forwards}
@@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["../scss/minimal.scss"],"names":[],"mappings":"AAIA;EACE;IACE;;EAEF;IACE;;;AAIJ;EACE","file":"ReactToastify.minimal.css"}
+8
View File
@@ -0,0 +1,8 @@
import * as React from 'react';
import { TypeOptions } from '../types';
export interface CloseButtonProps {
closeToast: (e: React.MouseEvent<HTMLElement>) => void;
type: TypeOptions;
ariaLabel?: string;
}
export declare function CloseButton({ closeToast, type, ariaLabel }: CloseButtonProps): JSX.Element;
+55
View File
@@ -0,0 +1,55 @@
import * as React from 'react';
import { TypeOptions, ToastClassName } from '../types';
export interface ProgressBarProps {
/**
* The animation delay which determine when to close the toast
*/
delay: number;
/**
* Whether or not the animation is running or paused
*/
isRunning: boolean;
/**
* Func to close the current toast
*/
closeToast: () => void;
/**
* Optional type : info, success ...
*/
type: TypeOptions;
/**
* Hide or not the progress bar
*/
hide?: boolean;
/**
* Optionnal className
*/
className?: ToastClassName;
/**
* Optionnal inline style
*/
style?: React.CSSProperties;
/**
* Tell wether or not controlled progress bar is used
*/
controlledProgress?: boolean;
/**
* Controlled progress value
*/
progress?: number | string;
/**
* Support rtl content
*/
rtl?: boolean;
/**
* Tell if the component is visible on screen or not
*/
isIn?: boolean;
}
export declare function ProgressBar({ delay, isRunning, closeToast, type, hide, className, style: userStyle, controlledProgress, progress, rtl, isIn }: ProgressBarProps): JSX.Element;
export declare namespace ProgressBar {
var defaultProps: {
type: TypeOptions;
hide: boolean;
};
}
+3
View File
@@ -0,0 +1,3 @@
import * as React from 'react';
import { ToastProps } from '../types';
export declare const Toast: React.FC<ToastProps>;
@@ -0,0 +1,3 @@
import * as React from 'react';
import { ToastContainerProps } from '../types';
export declare const ToastContainer: React.FC<ToastContainerProps>;
+5
View File
@@ -0,0 +1,5 @@
declare const Bounce: ({ children, position, preventExitTransition, done, nodeRef, isIn }: import("..").ToastTransitionProps) => JSX.Element;
declare const Slide: ({ children, position, preventExitTransition, done, nodeRef, isIn }: import("..").ToastTransitionProps) => JSX.Element;
declare const Zoom: ({ children, position, preventExitTransition, done, nodeRef, isIn }: import("..").ToastTransitionProps) => JSX.Element;
declare const Flip: ({ children, position, preventExitTransition, done, nodeRef, isIn }: import("..").ToastTransitionProps) => JSX.Element;
export { Bounce, Slide, Zoom, Flip };
+5
View File
@@ -0,0 +1,5 @@
export * from './CloseButton';
export * from './ProgressBar';
export * from './ToastContainer';
export * from './Transitions';
export * from './Toast';
+39
View File
@@ -0,0 +1,39 @@
/// <reference types="react" />
import { Id, ToastContent, ClearWaitingQueueParams, NotValidatedToastProps } from '../types';
import { ContainerInstance } from '../hooks';
export declare const enum Event {
Show = 0,
Clear = 1,
DidMount = 2,
WillUnmount = 3,
Change = 4,
ClearWaitingQueue = 5
}
declare type OnShowCallback = (content: ToastContent, options: NotValidatedToastProps) => void;
declare type OnClearCallback = (id?: Id) => void;
declare type OnClearWaitingQueue = (params: ClearWaitingQueueParams) => void;
declare type OnDidMountCallback = (containerInstance: ContainerInstance) => void;
declare type OnWillUnmountCallback = OnDidMountCallback;
export declare type OnChangeCallback = (toast: number, containerId?: number | string) => void;
declare type Callback = OnShowCallback | OnClearCallback | OnClearWaitingQueue | OnDidMountCallback | OnWillUnmountCallback | OnChangeCallback;
declare type TimeoutId = ReturnType<typeof window.setTimeout>;
export interface EventManager {
list: Map<Event, Callback[]>;
emitQueue: Map<Event, TimeoutId[]>;
on(event: Event.Show, callback: OnShowCallback): EventManager;
on(event: Event.Clear, callback: OnClearCallback): EventManager;
on(event: Event.ClearWaitingQueue, callback: OnClearWaitingQueue): EventManager;
on(event: Event.DidMount, callback: OnDidMountCallback): EventManager;
on(event: Event.WillUnmount, callback: OnWillUnmountCallback): EventManager;
on(event: Event.Change, callback: OnChangeCallback): EventManager;
off(event: Event, callback?: Callback): EventManager;
cancelEmit(event: Event): EventManager;
emit(event: Event.Show, content: React.ReactNode, options: NotValidatedToastProps): void;
emit(event: Event.Clear, id?: string | number): void;
emit(event: Event.ClearWaitingQueue, params: ClearWaitingQueueParams): void;
emit(event: Event.DidMount, containerInstance: ContainerInstance): void;
emit(event: Event.WillUnmount, containerInstance: ContainerInstance): void;
emit(event: Event.Change, toast: number, containerId?: number | string): void;
}
export declare const eventManager: EventManager;
export {};
+2
View File
@@ -0,0 +1,2 @@
export * from './eventManager';
export * from './toast';
+55
View File
@@ -0,0 +1,55 @@
import * as React from 'react';
import { OnChangeCallback } from './eventManager';
import { ToastContent, ToastOptions, Id, ToastContainerProps, UpdateOptions, ClearWaitingQueueParams } from '../types';
declare const toast: {
(content: ToastContent, options?: ToastOptions | undefined): React.ReactText;
success: (content: ToastContent, options?: ToastOptions | undefined) => React.ReactText;
info: (content: ToastContent, options?: ToastOptions | undefined) => React.ReactText;
error: (content: ToastContent, options?: ToastOptions | undefined) => React.ReactText;
warning: (content: ToastContent, options?: ToastOptions | undefined) => React.ReactText;
dark: (content: ToastContent, options?: ToastOptions | undefined) => React.ReactText;
warn: (content: ToastContent, options?: ToastOptions | undefined) => React.ReactText;
/**
* Remove toast programmaticaly
*/
dismiss(id?: string | number | undefined): void;
/**
* Clear waiting queue when limit is used
*/
clearWaitingQueue(params?: ClearWaitingQueueParams): void;
/**
* return true if one container is displaying the toast
*/
isActive(id: Id): boolean;
update(toastId: Id, options?: UpdateOptions): void;
/**
* Used for controlled progress bar.
*/
done(id: Id): void;
/**
* Track changes. The callback get the number of toast displayed
*
*/
onChange(callback: OnChangeCallback): () => void;
/**
* Configure the ToastContainer when lazy mounted
*/
configure(config?: ToastContainerProps): void;
POSITION: {
TOP_LEFT: import("../types").ToastPosition;
TOP_RIGHT: import("../types").ToastPosition;
TOP_CENTER: import("../types").ToastPosition;
BOTTOM_LEFT: import("../types").ToastPosition;
BOTTOM_RIGHT: import("../types").ToastPosition;
BOTTOM_CENTER: import("../types").ToastPosition;
};
TYPE: {
INFO: import("../types").TypeOptions;
SUCCESS: import("../types").TypeOptions;
WARNING: import("../types").TypeOptions;
ERROR: import("../types").TypeOptions;
DEFAULT: import("../types").TypeOptions;
DARK: import("../types").TypeOptions;
};
};
export { toast };
+3
View File
@@ -0,0 +1,3 @@
export * from './useToastContainer';
export * from './useToast';
export * from './useKeeper';
@@ -0,0 +1,15 @@
import { Id } from '../types';
export declare const enum ActionType {
ADD = 0,
REMOVE = 1
}
export declare type State = Array<Id>;
export declare type Action = {
type: ActionType.ADD;
toastId: Id;
staleId?: Id;
} | {
type: ActionType.REMOVE;
toastId?: Id;
};
export declare function reducer(state: State, action: Action): Id[];
+7
View File
@@ -0,0 +1,7 @@
/**
* `useKeeper` is a helper around `useRef`.
*
* You don't need to access the `.current`property to get the value
* If refresh is set to true. The ref will be updated every render
*/
export declare function useKeeper<T>(arg: T, refresh?: boolean): T;
+10
View File
@@ -0,0 +1,10 @@
import { DOMAttributes } from 'react';
import { ToastProps } from '../types';
export declare function useToast(props: ToastProps): {
playToast: () => void;
pauseToast: () => void;
isRunning: boolean;
preventExitTransition: boolean;
toastRef: import("react").RefObject<HTMLDivElement>;
eventHandlers: DOMAttributes<HTMLElement>;
};
+16
View File
@@ -0,0 +1,16 @@
/// <reference types="react" />
import { Id, ToastContainerProps, Toast, ToastPosition } from '../types';
export interface ContainerInstance {
toastKey: number;
displayedToast: number;
props: ToastContainerProps;
containerId?: Id | null;
isToastActive: (toastId: Id) => boolean;
getToast: (id: Id) => Toast | null;
}
export declare function useToastContainer(props: ToastContainerProps): {
getToastToRender: <T>(cb: (position: ToastPosition, toastList: Toast[]) => T) => T[];
collection: Record<Id, Toast>;
containerRef: import("react").MutableRefObject<null>;
isToastActive: (id: Id) => boolean;
};
+5
View File
@@ -0,0 +1,5 @@
export { useToastContainer, useToast } from './hooks';
export { cssTransition, collapseToast } from './utils';
export { ToastContainer, Bounce, Flip, Slide, Zoom } from './components';
export { toast } from './core';
export * from './types';
+8
View File
@@ -0,0 +1,8 @@
'use strict'
if (process.env.NODE_ENV === 'production') {
module.exports = require('./react-toastify.cjs.production.min.js')
} else {
module.exports = require('./react-toastify.cjs.development.js')
}
+8
View File
@@ -0,0 +1,8 @@
/**
* Inject the style in case you cannot import the css file
* Call it once in your app
*/
export declare function injectStyle(): void;
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,1306 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var React = require('react');
var React__default = _interopDefault(React);
var cx = _interopDefault(require('clsx'));
var reactDom = require('react-dom');
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function isNum(v) {
return typeof v === 'number' && !isNaN(v);
}
function isBool(v) {
return typeof v === 'boolean';
}
function isStr(v) {
return typeof v === 'string';
}
function isFn(v) {
return typeof v === 'function';
}
function parseClassName(v) {
return isStr(v) || isFn(v) ? v : null;
}
function isToastIdValid(toastId) {
return toastId === 0 || toastId;
}
function getAutoCloseDelay(toastAutoClose, containerAutoClose) {
return toastAutoClose === false || isNum(toastAutoClose) && toastAutoClose > 0 ? toastAutoClose : containerAutoClose;
}
var canUseDom = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
function canBeRendered(content) {
return React.isValidElement(content) || isStr(content) || isFn(content) || isNum(content);
}
var POSITION = {
TOP_LEFT: 'top-left',
TOP_RIGHT: 'top-right',
TOP_CENTER: 'top-center',
BOTTOM_LEFT: 'bottom-left',
BOTTOM_RIGHT: 'bottom-right',
BOTTOM_CENTER: 'bottom-center'
};
var TYPE = {
INFO: 'info',
SUCCESS: 'success',
WARNING: 'warning',
ERROR: 'error',
DEFAULT: 'default',
DARK: 'dark'
};
/**
* Used to collapse toast after exit animation
*/
function collapseToast(node, done, duration
/* COLLAPSE_DURATION */
) {
if (duration === void 0) {
duration = 300;
}
var height = node.scrollHeight;
var style = node.style;
requestAnimationFrame(function () {
style.minHeight = 'initial';
style.height = height + 'px';
style.transition = "all " + duration + "ms";
requestAnimationFrame(function () {
style.height = '0';
style.padding = '0';
style.margin = '0';
setTimeout(done, duration);
});
});
}
/**
* Css animation that just work.
* You could use animate.css for instance
*
*
* ```
* cssTransition({
* enter: "animate__animated animate__bounceIn",
* exit: "animate__animated animate__bounceOut"
* })
* ```
*
*/
function cssTransition(_ref) {
var enter = _ref.enter,
exit = _ref.exit,
_ref$appendPosition = _ref.appendPosition,
appendPosition = _ref$appendPosition === void 0 ? false : _ref$appendPosition,
_ref$collapse = _ref.collapse,
collapse = _ref$collapse === void 0 ? true : _ref$collapse,
_ref$collapseDuration = _ref.collapseDuration,
collapseDuration = _ref$collapseDuration === void 0 ? 300 : _ref$collapseDuration;
return function ToastTransition(_ref2) {
var children = _ref2.children,
position = _ref2.position,
preventExitTransition = _ref2.preventExitTransition,
done = _ref2.done,
nodeRef = _ref2.nodeRef,
isIn = _ref2.isIn;
var enterClassName = appendPosition ? enter + "--" + position : enter;
var exitClassName = appendPosition ? exit + "--" + position : exit;
var baseClassName = React.useRef();
var animationStep = React.useRef(0
/* Enter */
);
React.useLayoutEffect(function () {
onEnter();
}, []);
React.useEffect(function () {
if (!isIn) preventExitTransition ? onExited() : onExit();
}, [isIn]);
function onEnter() {
var node = nodeRef.current;
baseClassName.current = node.className;
node.className += " " + enterClassName;
node.addEventListener('animationend', onEntered);
}
function onEntered() {
var node = nodeRef.current;
node.removeEventListener('animationend', onEntered);
if (animationStep.current === 0
/* Enter */
) {
node.className = baseClassName.current;
}
}
function onExit() {
animationStep.current = 1
/* Exit */
;
var node = nodeRef.current;
node.className += " " + exitClassName;
node.addEventListener('animationend', onExited);
}
function onExited() {
var node = nodeRef.current;
node.removeEventListener('animationend', onExited);
collapse ? collapseToast(node, done, collapseDuration) : done();
}
return React__default.createElement(React__default.Fragment, null, children);
};
}
var eventManager = {
list: /*#__PURE__*/new Map(),
emitQueue: /*#__PURE__*/new Map(),
on: function on(event, callback) {
this.list.has(event) || this.list.set(event, []);
this.list.get(event).push(callback);
return this;
},
off: function off(event, callback) {
if (callback) {
var cb = this.list.get(event).filter(function (cb) {
return cb !== callback;
});
this.list.set(event, cb);
return this;
}
this.list["delete"](event);
return this;
},
cancelEmit: function cancelEmit(event) {
var timers = this.emitQueue.get(event);
if (timers) {
timers.forEach(clearTimeout);
this.emitQueue["delete"](event);
}
return this;
},
/**
* Enqueue the event at the end of the call stack
* Doing so let the user call toast as follow:
* toast('1')
* toast('2')
* toast('3')
* Without setTimemout the code above will not work
*/
emit: function emit(event) {
var _this = this;
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
this.list.has(event) && this.list.get(event).forEach(function (callback) {
var timer = setTimeout(function () {
// @ts-ignore
callback.apply(void 0, args);
}, 0);
_this.emitQueue.has(event) || _this.emitQueue.set(event, []);
_this.emitQueue.get(event).push(timer);
});
}
};
/**
* `useKeeper` is a helper around `useRef`.
*
* You don't need to access the `.current`property to get the value
* If refresh is set to true. The ref will be updated every render
*/
function useKeeper(arg, refresh) {
if (refresh === void 0) {
refresh = false;
}
var ref = React.useRef(arg);
React.useEffect(function () {
if (refresh) ref.current = arg;
});
return ref.current;
}
function reducer(state, action) {
switch (action.type) {
case 0
/* ADD */
:
return [].concat(state, [action.toastId]).filter(function (id) {
return id !== action.staleId;
});
case 1
/* REMOVE */
:
return isToastIdValid(action.toastId) ? state.filter(function (id) {
return id !== action.toastId;
}) : [];
}
}
function useToastContainer(props) {
var _useReducer = React.useReducer(function (x) {
return x + 1;
}, 0),
forceUpdate = _useReducer[1];
var _useReducer2 = React.useReducer(reducer, []),
toast = _useReducer2[0],
dispatch = _useReducer2[1];
var containerRef = React.useRef(null);
var toastCount = useKeeper(0);
var queue = useKeeper([]);
var collection = useKeeper({});
var instance = useKeeper({
toastKey: 1,
displayedToast: 0,
props: props,
containerId: null,
isToastActive: isToastActive,
getToast: function getToast(id) {
return collection[id] || null;
}
});
React.useEffect(function () {
instance.containerId = props.containerId;
eventManager.cancelEmit(3
/* WillUnmount */
).on(0
/* Show */
, buildToast).on(1
/* Clear */
, function (toastId) {
return containerRef.current && removeToast(toastId);
}).on(5
/* ClearWaitingQueue */
, clearWaitingQueue).emit(2
/* DidMount */
, instance);
return function () {
return eventManager.emit(3
/* WillUnmount */
, instance);
};
}, []);
React.useEffect(function () {
instance.isToastActive = isToastActive;
instance.displayedToast = toast.length;
eventManager.emit(4
/* Change */
, toast.length, props.containerId);
}, [toast]);
React.useEffect(function () {
instance.props = props;
});
function isToastActive(id) {
return toast.indexOf(id) !== -1;
}
function clearWaitingQueue(_ref) {
var containerId = _ref.containerId;
var limit = instance.props.limit;
if (limit && (!containerId || instance.containerId === containerId)) {
toastCount -= queue.length;
queue = [];
}
}
function removeToast(toastId) {
dispatch({
type: 1
/* REMOVE */
,
toastId: toastId
});
}
function dequeueToast() {
var _queue$shift = queue.shift(),
toastContent = _queue$shift.toastContent,
toastProps = _queue$shift.toastProps,
staleId = _queue$shift.staleId;
appendToast(toastContent, toastProps, staleId);
}
/**
* check if a container is attached to the dom
* check for multi-container, build only if associated
* check for duplicate toastId if no update
*/
function isNotValid(_ref2) {
var containerId = _ref2.containerId,
toastId = _ref2.toastId,
updateId = _ref2.updateId;
return !containerRef.current || instance.props.enableMultiContainer && containerId !== instance.props.containerId || collection[toastId] && updateId == null ? true : false;
} // this function and all the function called inside needs to rely on ref(`useKeeper`)
function buildToast(content, _ref3) {
var delay = _ref3.delay,
staleId = _ref3.staleId,
options = _objectWithoutPropertiesLoose(_ref3, ["delay", "staleId"]);
if (!canBeRendered(content) || isNotValid(options)) return;
var toastId = options.toastId,
updateId = options.updateId;
var props = instance.props;
var closeToast = function closeToast() {
return removeToast(toastId);
};
var isNotAnUpdate = options.updateId == null;
if (isNotAnUpdate) toastCount++;
var toastProps = {
toastId: toastId,
updateId: updateId,
isIn: false,
key: options.key || instance.toastKey++,
type: options.type,
closeToast: closeToast,
closeButton: options.closeButton,
rtl: props.rtl,
position: options.position || props.position,
transition: options.transition || props.transition,
className: parseClassName(options.className || props.toastClassName),
bodyClassName: parseClassName(options.bodyClassName || props.bodyClassName),
style: options.style || props.toastStyle,
bodyStyle: options.bodyStyle || props.bodyStyle,
onClick: options.onClick || props.onClick,
pauseOnHover: isBool(options.pauseOnHover) ? options.pauseOnHover : props.pauseOnHover,
pauseOnFocusLoss: isBool(options.pauseOnFocusLoss) ? options.pauseOnFocusLoss : props.pauseOnFocusLoss,
draggable: isBool(options.draggable) ? options.draggable : props.draggable,
draggablePercent: isNum(options.draggablePercent) ? options.draggablePercent : props.draggablePercent,
draggableDirection: options.draggableDirection || props.draggableDirection,
closeOnClick: isBool(options.closeOnClick) ? options.closeOnClick : props.closeOnClick,
progressClassName: parseClassName(options.progressClassName || props.progressClassName),
progressStyle: options.progressStyle || props.progressStyle,
autoClose: getAutoCloseDelay(options.autoClose, props.autoClose),
hideProgressBar: isBool(options.hideProgressBar) ? options.hideProgressBar : props.hideProgressBar,
progress: options.progress,
role: isStr(options.role) ? options.role : props.role,
deleteToast: function deleteToast() {
removeFromCollection(toastId);
}
};
if (isFn(options.onOpen)) toastProps.onOpen = options.onOpen;
if (isFn(options.onClose)) toastProps.onClose = options.onClose; // tweak for vertical dragging
if (toastProps.draggableDirection === "y"
/* Y */
&& toastProps.draggablePercent === 80
/* DRAGGABLE_PERCENT */
) {
toastProps.draggablePercent *= 1.5;
}
var closeButton = props.closeButton;
if (options.closeButton === false || canBeRendered(options.closeButton)) {
closeButton = options.closeButton;
} else if (options.closeButton === true) {
closeButton = canBeRendered(props.closeButton) ? props.closeButton : true;
}
toastProps.closeButton = closeButton;
var toastContent = content;
if (React.isValidElement(content) && !isStr(content.type)) {
toastContent = React.cloneElement(content, {
closeToast: closeToast,
toastProps: toastProps
});
} else if (isFn(content)) {
toastContent = content({
closeToast: closeToast,
toastProps: toastProps
});
} // not handling limit + delay by design. Waiting for user feedback first
if (props.limit && props.limit > 0 && toastCount > props.limit && isNotAnUpdate) {
queue.push({
toastContent: toastContent,
toastProps: toastProps,
staleId: staleId
});
} else if (isNum(delay) && delay > 0) {
setTimeout(function () {
appendToast(toastContent, toastProps, staleId);
}, delay);
} else {
appendToast(toastContent, toastProps, staleId);
}
}
function appendToast(content, toastProps, staleId) {
var toastId = toastProps.toastId;
if (staleId) delete collection[staleId];
collection[toastId] = {
content: content,
props: toastProps
};
dispatch({
type: 0
/* ADD */
,
toastId: toastId,
staleId: staleId
});
}
function removeFromCollection(toastId) {
delete collection[toastId];
var queueLen = queue.length;
toastCount = isToastIdValid(toastId) ? toastCount - 1 : toastCount - instance.displayedToast;
if (toastCount < 0) toastCount = 0;
if (queueLen > 0) {
var freeSlot = isToastIdValid(toastId) ? 1 : instance.props.limit;
if (queueLen === 1 || freeSlot === 1) {
instance.displayedToast++;
dequeueToast();
} else {
var toDequeue = freeSlot > queueLen ? queueLen : freeSlot;
instance.displayedToast = toDequeue;
for (var i = 0; i < toDequeue; i++) {
dequeueToast();
}
}
} else {
forceUpdate();
}
}
function getToastToRender(cb) {
var toastToRender = {};
var toastList = props.newestOnTop ? Object.keys(collection).reverse() : Object.keys(collection);
for (var i = 0; i < toastList.length; i++) {
var _toast = collection[toastList[i]];
var position = _toast.props.position;
toastToRender[position] || (toastToRender[position] = []);
toastToRender[position].push(_toast);
}
return Object.keys(toastToRender).map(function (p) {
return cb(p, toastToRender[p]);
});
}
return {
getToastToRender: getToastToRender,
collection: collection,
containerRef: containerRef,
isToastActive: isToastActive
};
}
function getX(e) {
return e.targetTouches && e.targetTouches.length >= 1 ? e.targetTouches[0].clientX : e.clientX;
}
function getY(e) {
return e.targetTouches && e.targetTouches.length >= 1 ? e.targetTouches[0].clientY : e.clientY;
}
function useToast(props) {
var _useState = React.useState(true),
isRunning = _useState[0],
setIsRunning = _useState[1];
var _useState2 = React.useState(false),
preventExitTransition = _useState2[0],
setPreventExitTransition = _useState2[1];
var toastRef = React.useRef(null);
var drag = useKeeper({
start: 0,
x: 0,
y: 0,
delta: 0,
removalDistance: 0,
canCloseOnClick: true,
canDrag: false,
boundingRect: null
});
var syncProps = useKeeper(props, true);
var autoClose = props.autoClose,
pauseOnHover = props.pauseOnHover,
closeToast = props.closeToast,
onClick = props.onClick,
closeOnClick = props.closeOnClick;
React.useEffect(function () {
if (isFn(props.onOpen)) props.onOpen(React.isValidElement(props.children) && props.children.props);
return function () {
if (isFn(syncProps.onClose)) syncProps.onClose(React.isValidElement(syncProps.children) && syncProps.children.props);
};
}, []);
React.useEffect(function () {
props.draggable && bindDragEvents();
return function () {
props.draggable && unbindDragEvents();
};
}, [props.draggable]);
React.useEffect(function () {
props.pauseOnFocusLoss && bindFocusEvents();
return function () {
props.pauseOnFocusLoss && unbindFocusEvents();
};
}, [props.pauseOnFocusLoss]);
function onDragStart(e) {
if (props.draggable) {
var toast = toastRef.current;
drag.canCloseOnClick = true;
drag.canDrag = true;
drag.boundingRect = toast.getBoundingClientRect();
toast.style.transition = '';
drag.x = getX(e.nativeEvent);
drag.y = getY(e.nativeEvent);
if (props.draggableDirection === "x"
/* X */
) {
drag.start = drag.x;
drag.removalDistance = toast.offsetWidth * (props.draggablePercent / 100);
} else {
drag.start = drag.y;
drag.removalDistance = toast.offsetHeight * (props.draggablePercent / 100);
}
}
}
function onDragTransitionEnd() {
if (drag.boundingRect) {
var _drag$boundingRect = drag.boundingRect,
top = _drag$boundingRect.top,
bottom = _drag$boundingRect.bottom,
left = _drag$boundingRect.left,
right = _drag$boundingRect.right;
if (props.pauseOnHover && drag.x >= left && drag.x <= right && drag.y >= top && drag.y <= bottom) {
pauseToast();
} else {
playToast();
}
}
}
function playToast() {
setIsRunning(true);
}
function pauseToast() {
setIsRunning(false);
}
function bindFocusEvents() {
if (!document.hasFocus()) pauseToast();
window.addEventListener('focus', playToast);
window.addEventListener('blur', pauseToast);
}
function unbindFocusEvents() {
window.removeEventListener('focus', playToast);
window.removeEventListener('blur', pauseToast);
}
function bindDragEvents() {
document.addEventListener('mousemove', onDragMove);
document.addEventListener('mouseup', onDragEnd);
document.addEventListener('touchmove', onDragMove);
document.addEventListener('touchend', onDragEnd);
}
function unbindDragEvents() {
document.removeEventListener('mousemove', onDragMove);
document.removeEventListener('mouseup', onDragEnd);
document.removeEventListener('touchmove', onDragMove);
document.removeEventListener('touchend', onDragEnd);
}
function onDragMove(e) {
if (drag.canDrag) {
e.preventDefault();
var toast = toastRef.current;
if (isRunning) pauseToast();
drag.x = getX(e);
drag.y = getY(e);
if (props.draggableDirection === "x"
/* X */
) {
drag.delta = drag.x - drag.start;
} else {
drag.delta = drag.y - drag.start;
} // prevent false positif during a toast click
if (drag.start !== drag.x) drag.canCloseOnClick = false;
toast.style.transform = "translate" + props.draggableDirection + "(" + drag.delta + "px)";
toast.style.opacity = "" + (1 - Math.abs(drag.delta / drag.removalDistance));
}
}
function onDragEnd() {
var toast = toastRef.current;
if (drag.canDrag) {
drag.canDrag = false;
if (Math.abs(drag.delta) > drag.removalDistance) {
setPreventExitTransition(true);
props.closeToast();
return;
}
toast.style.transition = 'transform 0.2s, opacity 0.2s';
toast.style.transform = "translate" + props.draggableDirection + "(0)";
toast.style.opacity = '1';
}
}
var eventHandlers = {
onMouseDown: onDragStart,
onTouchStart: onDragStart,
onMouseUp: onDragTransitionEnd,
onTouchEnd: onDragTransitionEnd
};
if (autoClose && pauseOnHover) {
eventHandlers.onMouseEnter = pauseToast;
eventHandlers.onMouseLeave = playToast;
} // prevent toast from closing when user drags the toast
if (closeOnClick) {
eventHandlers.onClick = function (e) {
onClick && onClick(e);
drag.canCloseOnClick && closeToast();
};
}
return {
playToast: playToast,
pauseToast: pauseToast,
isRunning: isRunning,
preventExitTransition: preventExitTransition,
toastRef: toastRef,
eventHandlers: eventHandlers
};
}
function CloseButton(_ref) {
var closeToast = _ref.closeToast,
type = _ref.type,
_ref$ariaLabel = _ref.ariaLabel,
ariaLabel = _ref$ariaLabel === void 0 ? 'close' : _ref$ariaLabel;
return React.createElement("button", {
className: "Toastify"
/* CSS_NAMESPACE */
+ "__close-button " + "Toastify"
/* CSS_NAMESPACE */
+ "__close-button--" + type,
type: "button",
onClick: function onClick(e) {
e.stopPropagation();
closeToast(e);
},
"aria-label": ariaLabel
}, React.createElement("svg", {
"aria-hidden": "true",
viewBox: "0 0 14 16"
}, React.createElement("path", {
fillRule: "evenodd",
d: "M7.71 8.23l3.75 3.75-1.48 1.48-3.75-3.75-3.75 3.75L1 11.98l3.75-3.75L1 4.48 2.48 3l3.75 3.75L9.98 3l1.48 1.48-3.75 3.75z"
})));
}
function ProgressBar(_ref) {
var _cx, _animationEvent;
var delay = _ref.delay,
isRunning = _ref.isRunning,
closeToast = _ref.closeToast,
type = _ref.type,
hide = _ref.hide,
className = _ref.className,
userStyle = _ref.style,
controlledProgress = _ref.controlledProgress,
progress = _ref.progress,
rtl = _ref.rtl,
isIn = _ref.isIn;
var style = _extends({}, userStyle, {
animationDuration: delay + "ms",
animationPlayState: isRunning ? 'running' : 'paused',
opacity: hide ? 0 : 1
});
if (controlledProgress) style.transform = "scaleX(" + progress + ")";
var defaultClassName = cx("Toastify"
/* CSS_NAMESPACE */
+ "__progress-bar", controlledProgress ? "Toastify"
/* CSS_NAMESPACE */
+ "__progress-bar--controlled" : "Toastify"
/* CSS_NAMESPACE */
+ "__progress-bar--animated", "Toastify"
/* CSS_NAMESPACE */
+ "__progress-bar--" + type, (_cx = {}, _cx["Toastify"
/* CSS_NAMESPACE */
+ "__progress-bar--rtl"] = rtl, _cx));
var classNames = isFn(className) ? className({
rtl: rtl,
type: type,
defaultClassName: defaultClassName
}) : cx(defaultClassName, className); // 🧐 controlledProgress is derived from progress
// so if controlledProgress is set
// it means that this is also the case for progress
var animationEvent = (_animationEvent = {}, _animationEvent[controlledProgress && progress >= 1 ? 'onTransitionEnd' : 'onAnimationEnd'] = controlledProgress && progress < 1 ? null : function () {
isIn && closeToast();
}, _animationEvent); // TODO: add aria-valuenow, aria-valuemax, aria-valuemin
return React.createElement("div", Object.assign({
role: "progressbar",
"aria-hidden": hide ? 'true' : 'false',
"aria-label": "notification timer",
className: classNames,
style: style
}, animationEvent));
}
ProgressBar.defaultProps = {
type: TYPE.DEFAULT,
hide: false
};
var Toast = function Toast(props) {
var _cx;
var _useToast = useToast(props),
isRunning = _useToast.isRunning,
preventExitTransition = _useToast.preventExitTransition,
toastRef = _useToast.toastRef,
eventHandlers = _useToast.eventHandlers;
var closeButton = props.closeButton,
children = props.children,
autoClose = props.autoClose,
onClick = props.onClick,
type = props.type,
hideProgressBar = props.hideProgressBar,
closeToast = props.closeToast,
Transition = props.transition,
position = props.position,
className = props.className,
style = props.style,
bodyClassName = props.bodyClassName,
bodyStyle = props.bodyStyle,
progressClassName = props.progressClassName,
progressStyle = props.progressStyle,
updateId = props.updateId,
role = props.role,
progress = props.progress,
rtl = props.rtl,
toastId = props.toastId,
deleteToast = props.deleteToast,
isIn = props.isIn;
var defaultClassName = cx("Toastify"
/* CSS_NAMESPACE */
+ "__toast", "Toastify"
/* CSS_NAMESPACE */
+ "__toast--" + type, (_cx = {}, _cx["Toastify"
/* CSS_NAMESPACE */
+ "__toast--rtl"] = rtl, _cx));
var cssClasses = isFn(className) ? className({
rtl: rtl,
position: position,
type: type,
defaultClassName: defaultClassName
}) : cx(defaultClassName, className);
var isProgressControlled = !!progress;
function renderCloseButton(closeButton) {
if (!closeButton) return;
var props = {
closeToast: closeToast,
type: type
};
if (isFn(closeButton)) return closeButton(props);
if (React.isValidElement(closeButton)) return React.cloneElement(closeButton, props);
}
return React.createElement(Transition, {
isIn: isIn,
done: deleteToast,
position: position,
preventExitTransition: preventExitTransition,
nodeRef: toastRef
}, React.createElement("div", Object.assign({
id: toastId,
onClick: onClick,
className: cssClasses
}, eventHandlers, {
style: style,
ref: toastRef
}), React.createElement("div", Object.assign({}, isIn && {
role: role
}, {
className: isFn(bodyClassName) ? bodyClassName({
type: type
}) : cx("Toastify"
/* CSS_NAMESPACE */
+ "__toast-body", bodyClassName),
style: bodyStyle
}), children), renderCloseButton(closeButton), (autoClose || isProgressControlled) && React.createElement(ProgressBar, Object.assign({}, updateId && !isProgressControlled ? {
key: "pb-" + updateId
} : {}, {
rtl: rtl,
delay: autoClose,
isRunning: isRunning,
isIn: isIn,
closeToast: closeToast,
hide: hideProgressBar,
type: type,
style: progressStyle,
className: progressClassName,
controlledProgress: isProgressControlled,
progress: progress
}))));
};
var Bounce = /*#__PURE__*/cssTransition({
enter: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__bounce-enter",
exit: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__bounce-exit",
appendPosition: true
});
var Slide = /*#__PURE__*/cssTransition({
enter: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__slide-enter",
exit: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__slide-exit",
appendPosition: true
});
var Zoom = /*#__PURE__*/cssTransition({
enter: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__zoom-enter",
exit: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__zoom-exit"
});
var Flip = /*#__PURE__*/cssTransition({
enter: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__flip-enter",
exit: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__flip-exit"
});
var ToastContainer = function ToastContainer(props) {
var _useToastContainer = useToastContainer(props),
getToastToRender = _useToastContainer.getToastToRender,
containerRef = _useToastContainer.containerRef,
isToastActive = _useToastContainer.isToastActive;
var className = props.className,
style = props.style,
rtl = props.rtl,
containerId = props.containerId;
function getClassName(position) {
var _cx;
var defaultClassName = cx("Toastify"
/* CSS_NAMESPACE */
+ "__toast-container", "Toastify"
/* CSS_NAMESPACE */
+ "__toast-container--" + position, (_cx = {}, _cx["Toastify"
/* CSS_NAMESPACE */
+ "__toast-container--rtl"] = rtl, _cx));
return isFn(className) ? className({
position: position,
rtl: rtl,
defaultClassName: defaultClassName
}) : cx(defaultClassName, parseClassName(className));
}
return React.createElement("div", {
ref: containerRef,
className: "Toastify"
/* CSS_NAMESPACE */
,
id: containerId
}, getToastToRender(function (position, toastList) {
var containerStyle = toastList.length === 0 ? _extends({}, style, {
pointerEvents: 'none'
}) : _extends({}, style);
return React.createElement("div", {
className: getClassName(position),
style: containerStyle,
key: "container-" + position
}, toastList.map(function (_ref) {
var content = _ref.content,
toastProps = _ref.props;
return React.createElement(Toast, Object.assign({}, toastProps, {
isIn: isToastActive(toastProps.toastId),
key: "toast-" + toastProps.key,
closeButton: toastProps.closeButton === true ? CloseButton : toastProps.closeButton
}), content);
}));
}));
};
ToastContainer.defaultProps = {
position: POSITION.TOP_RIGHT,
transition: Bounce,
rtl: false,
autoClose: 5000,
hideProgressBar: false,
closeButton: CloseButton,
pauseOnHover: true,
pauseOnFocusLoss: true,
closeOnClick: true,
newestOnTop: false,
draggable: true,
draggablePercent: 80
/* DRAGGABLE_PERCENT */
,
draggableDirection: "x"
/* X */
,
role: 'alert'
};
var containers = /*#__PURE__*/new Map();
var latestInstance;
var containerDomNode;
var containerConfig;
var queue = [];
var lazy = false;
/**
* Check whether any container is currently mounted in the DOM
*/
function isAnyContainerMounted() {
return containers.size > 0;
}
/**
* Get the toast by id, given it's in the DOM, otherwise returns null
*/
function getToast(toastId, _ref) {
var containerId = _ref.containerId;
var container = containers.get(containerId || latestInstance);
if (!container) return null;
return container.getToast(toastId);
}
/**
* Generate a random toastId
*/
function generateToastId() {
return Math.random().toString(36).substr(2, 9);
}
/**
* Generate a toastId or use the one provided
*/
function getToastId(options) {
if (options && (isStr(options.toastId) || isNum(options.toastId))) {
return options.toastId;
}
return generateToastId();
}
/**
* If the container is not mounted, the toast is enqueued and
* the container lazy mounted
*/
function dispatchToast(content, options) {
if (isAnyContainerMounted()) {
eventManager.emit(0
/* Show */
, content, options);
} else {
queue.push({
content: content,
options: options
});
if (lazy && canUseDom) {
lazy = false;
containerDomNode = document.createElement('div');
document.body.appendChild(containerDomNode);
reactDom.render(React.createElement(ToastContainer, Object.assign({}, containerConfig)), containerDomNode);
}
}
return options.toastId;
}
/**
* Merge provided options with the defaults settings and generate the toastId
*/
function mergeOptions(type, options) {
return _extends({}, options, {
type: options && options.type || type,
toastId: getToastId(options)
});
}
var createToastByType = function createToastByType(type) {
return function (content, options) {
return dispatchToast(content, mergeOptions(type, options));
};
};
var toast = function toast(content, options) {
return dispatchToast(content, mergeOptions(TYPE.DEFAULT, options));
};
toast.success = /*#__PURE__*/createToastByType(TYPE.SUCCESS);
toast.info = /*#__PURE__*/createToastByType(TYPE.INFO);
toast.error = /*#__PURE__*/createToastByType(TYPE.ERROR);
toast.warning = /*#__PURE__*/createToastByType(TYPE.WARNING);
toast.dark = /*#__PURE__*/createToastByType(TYPE.DARK);
toast.warn = toast.warning;
/**
* Remove toast programmaticaly
*/
toast.dismiss = function (id) {
return eventManager.emit(1
/* Clear */
, id);
};
/**
* Clear waiting queue when limit is used
*/
toast.clearWaitingQueue = function (params) {
if (params === void 0) {
params = {};
}
return eventManager.emit(5
/* ClearWaitingQueue */
, params);
};
/**
* return true if one container is displaying the toast
*/
toast.isActive = function (id) {
var isToastActive = false;
containers.forEach(function (container) {
if (container.isToastActive && container.isToastActive(id)) {
isToastActive = true;
}
});
return isToastActive;
};
toast.update = function (toastId, options) {
if (options === void 0) {
options = {};
}
// if you call toast and toast.update directly nothing will be displayed
// this is why I defered the update
setTimeout(function () {
var toast = getToast(toastId, options);
if (toast) {
var oldOptions = toast.props,
oldContent = toast.content;
var nextOptions = _extends({}, oldOptions, options, {
toastId: options.toastId || toastId,
updateId: generateToastId()
});
if (nextOptions.toastId !== toastId) nextOptions.staleId = toastId;
var content = nextOptions.render || oldContent;
delete nextOptions.render;
dispatchToast(content, nextOptions);
}
}, 0);
};
/**
* Used for controlled progress bar.
*/
toast.done = function (id) {
toast.update(id, {
progress: 1
});
};
/**
* Track changes. The callback get the number of toast displayed
*
*/
toast.onChange = function (callback) {
if (isFn(callback)) {
eventManager.on(4
/* Change */
, callback);
}
return function () {
isFn(callback) && eventManager.off(4
/* Change */
, callback);
};
};
/**
* Configure the ToastContainer when lazy mounted
*/
toast.configure = function (config) {
if (config === void 0) {
config = {};
}
lazy = true;
containerConfig = config;
};
toast.POSITION = POSITION;
toast.TYPE = TYPE;
/**
* Wait until the ToastContainer is mounted to dispatch the toast
* and attach isActive method
*/
eventManager.on(2
/* DidMount */
, function (containerInstance) {
latestInstance = containerInstance.containerId || containerInstance;
containers.set(latestInstance, containerInstance);
queue.forEach(function (item) {
eventManager.emit(0
/* Show */
, item.content, item.options);
});
queue = [];
}).on(3
/* WillUnmount */
, function (containerInstance) {
containers["delete"](containerInstance.containerId || containerInstance);
if (containers.size === 0) {
eventManager.off(0
/* Show */
).off(1
/* Clear */
).off(5
/* ClearWaitingQueue */
);
}
if (canUseDom && containerDomNode) {
document.body.removeChild(containerDomNode);
}
});
exports.Bounce = Bounce;
exports.Flip = Flip;
exports.Slide = Slide;
exports.ToastContainer = ToastContainer;
exports.Zoom = Zoom;
exports.collapseToast = collapseToast;
exports.cssTransition = cssTransition;
exports.toast = toast;
exports.useToast = useToast;
exports.useToastContainer = useToastContainer;
//# sourceMappingURL=react-toastify.cjs.development.js.map
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1290
View File
@@ -0,0 +1,1290 @@
import React__default, { isValidElement, useRef, useLayoutEffect, useEffect, useReducer, cloneElement, useState, createElement } from 'react';
import cx from 'clsx';
import { render } from 'react-dom';
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function isNum(v) {
return typeof v === 'number' && !isNaN(v);
}
function isBool(v) {
return typeof v === 'boolean';
}
function isStr(v) {
return typeof v === 'string';
}
function isFn(v) {
return typeof v === 'function';
}
function parseClassName(v) {
return isStr(v) || isFn(v) ? v : null;
}
function isToastIdValid(toastId) {
return toastId === 0 || toastId;
}
function getAutoCloseDelay(toastAutoClose, containerAutoClose) {
return toastAutoClose === false || isNum(toastAutoClose) && toastAutoClose > 0 ? toastAutoClose : containerAutoClose;
}
var canUseDom = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
function canBeRendered(content) {
return isValidElement(content) || isStr(content) || isFn(content) || isNum(content);
}
var POSITION = {
TOP_LEFT: 'top-left',
TOP_RIGHT: 'top-right',
TOP_CENTER: 'top-center',
BOTTOM_LEFT: 'bottom-left',
BOTTOM_RIGHT: 'bottom-right',
BOTTOM_CENTER: 'bottom-center'
};
var TYPE = {
INFO: 'info',
SUCCESS: 'success',
WARNING: 'warning',
ERROR: 'error',
DEFAULT: 'default',
DARK: 'dark'
};
/**
* Used to collapse toast after exit animation
*/
function collapseToast(node, done, duration
/* COLLAPSE_DURATION */
) {
if (duration === void 0) {
duration = 300;
}
var height = node.scrollHeight;
var style = node.style;
requestAnimationFrame(function () {
style.minHeight = 'initial';
style.height = height + 'px';
style.transition = "all " + duration + "ms";
requestAnimationFrame(function () {
style.height = '0';
style.padding = '0';
style.margin = '0';
setTimeout(done, duration);
});
});
}
/**
* Css animation that just work.
* You could use animate.css for instance
*
*
* ```
* cssTransition({
* enter: "animate__animated animate__bounceIn",
* exit: "animate__animated animate__bounceOut"
* })
* ```
*
*/
function cssTransition(_ref) {
var enter = _ref.enter,
exit = _ref.exit,
_ref$appendPosition = _ref.appendPosition,
appendPosition = _ref$appendPosition === void 0 ? false : _ref$appendPosition,
_ref$collapse = _ref.collapse,
collapse = _ref$collapse === void 0 ? true : _ref$collapse,
_ref$collapseDuration = _ref.collapseDuration,
collapseDuration = _ref$collapseDuration === void 0 ? 300 : _ref$collapseDuration;
return function ToastTransition(_ref2) {
var children = _ref2.children,
position = _ref2.position,
preventExitTransition = _ref2.preventExitTransition,
done = _ref2.done,
nodeRef = _ref2.nodeRef,
isIn = _ref2.isIn;
var enterClassName = appendPosition ? enter + "--" + position : enter;
var exitClassName = appendPosition ? exit + "--" + position : exit;
var baseClassName = useRef();
var animationStep = useRef(0
/* Enter */
);
useLayoutEffect(function () {
onEnter();
}, []);
useEffect(function () {
if (!isIn) preventExitTransition ? onExited() : onExit();
}, [isIn]);
function onEnter() {
var node = nodeRef.current;
baseClassName.current = node.className;
node.className += " " + enterClassName;
node.addEventListener('animationend', onEntered);
}
function onEntered() {
var node = nodeRef.current;
node.removeEventListener('animationend', onEntered);
if (animationStep.current === 0
/* Enter */
) {
node.className = baseClassName.current;
}
}
function onExit() {
animationStep.current = 1
/* Exit */
;
var node = nodeRef.current;
node.className += " " + exitClassName;
node.addEventListener('animationend', onExited);
}
function onExited() {
var node = nodeRef.current;
node.removeEventListener('animationend', onExited);
collapse ? collapseToast(node, done, collapseDuration) : done();
}
return React__default.createElement(React__default.Fragment, null, children);
};
}
var eventManager = {
list: /*#__PURE__*/new Map(),
emitQueue: /*#__PURE__*/new Map(),
on: function on(event, callback) {
this.list.has(event) || this.list.set(event, []);
this.list.get(event).push(callback);
return this;
},
off: function off(event, callback) {
if (callback) {
var cb = this.list.get(event).filter(function (cb) {
return cb !== callback;
});
this.list.set(event, cb);
return this;
}
this.list["delete"](event);
return this;
},
cancelEmit: function cancelEmit(event) {
var timers = this.emitQueue.get(event);
if (timers) {
timers.forEach(clearTimeout);
this.emitQueue["delete"](event);
}
return this;
},
/**
* Enqueue the event at the end of the call stack
* Doing so let the user call toast as follow:
* toast('1')
* toast('2')
* toast('3')
* Without setTimemout the code above will not work
*/
emit: function emit(event) {
var _this = this;
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
this.list.has(event) && this.list.get(event).forEach(function (callback) {
var timer = setTimeout(function () {
// @ts-ignore
callback.apply(void 0, args);
}, 0);
_this.emitQueue.has(event) || _this.emitQueue.set(event, []);
_this.emitQueue.get(event).push(timer);
});
}
};
/**
* `useKeeper` is a helper around `useRef`.
*
* You don't need to access the `.current`property to get the value
* If refresh is set to true. The ref will be updated every render
*/
function useKeeper(arg, refresh) {
if (refresh === void 0) {
refresh = false;
}
var ref = useRef(arg);
useEffect(function () {
if (refresh) ref.current = arg;
});
return ref.current;
}
function reducer(state, action) {
switch (action.type) {
case 0
/* ADD */
:
return [].concat(state, [action.toastId]).filter(function (id) {
return id !== action.staleId;
});
case 1
/* REMOVE */
:
return isToastIdValid(action.toastId) ? state.filter(function (id) {
return id !== action.toastId;
}) : [];
}
}
function useToastContainer(props) {
var _useReducer = useReducer(function (x) {
return x + 1;
}, 0),
forceUpdate = _useReducer[1];
var _useReducer2 = useReducer(reducer, []),
toast = _useReducer2[0],
dispatch = _useReducer2[1];
var containerRef = useRef(null);
var toastCount = useKeeper(0);
var queue = useKeeper([]);
var collection = useKeeper({});
var instance = useKeeper({
toastKey: 1,
displayedToast: 0,
props: props,
containerId: null,
isToastActive: isToastActive,
getToast: function getToast(id) {
return collection[id] || null;
}
});
useEffect(function () {
instance.containerId = props.containerId;
eventManager.cancelEmit(3
/* WillUnmount */
).on(0
/* Show */
, buildToast).on(1
/* Clear */
, function (toastId) {
return containerRef.current && removeToast(toastId);
}).on(5
/* ClearWaitingQueue */
, clearWaitingQueue).emit(2
/* DidMount */
, instance);
return function () {
return eventManager.emit(3
/* WillUnmount */
, instance);
};
}, []);
useEffect(function () {
instance.isToastActive = isToastActive;
instance.displayedToast = toast.length;
eventManager.emit(4
/* Change */
, toast.length, props.containerId);
}, [toast]);
useEffect(function () {
instance.props = props;
});
function isToastActive(id) {
return toast.indexOf(id) !== -1;
}
function clearWaitingQueue(_ref) {
var containerId = _ref.containerId;
var limit = instance.props.limit;
if (limit && (!containerId || instance.containerId === containerId)) {
toastCount -= queue.length;
queue = [];
}
}
function removeToast(toastId) {
dispatch({
type: 1
/* REMOVE */
,
toastId: toastId
});
}
function dequeueToast() {
var _queue$shift = queue.shift(),
toastContent = _queue$shift.toastContent,
toastProps = _queue$shift.toastProps,
staleId = _queue$shift.staleId;
appendToast(toastContent, toastProps, staleId);
}
/**
* check if a container is attached to the dom
* check for multi-container, build only if associated
* check for duplicate toastId if no update
*/
function isNotValid(_ref2) {
var containerId = _ref2.containerId,
toastId = _ref2.toastId,
updateId = _ref2.updateId;
return !containerRef.current || instance.props.enableMultiContainer && containerId !== instance.props.containerId || collection[toastId] && updateId == null ? true : false;
} // this function and all the function called inside needs to rely on ref(`useKeeper`)
function buildToast(content, _ref3) {
var delay = _ref3.delay,
staleId = _ref3.staleId,
options = _objectWithoutPropertiesLoose(_ref3, ["delay", "staleId"]);
if (!canBeRendered(content) || isNotValid(options)) return;
var toastId = options.toastId,
updateId = options.updateId;
var props = instance.props;
var closeToast = function closeToast() {
return removeToast(toastId);
};
var isNotAnUpdate = options.updateId == null;
if (isNotAnUpdate) toastCount++;
var toastProps = {
toastId: toastId,
updateId: updateId,
isIn: false,
key: options.key || instance.toastKey++,
type: options.type,
closeToast: closeToast,
closeButton: options.closeButton,
rtl: props.rtl,
position: options.position || props.position,
transition: options.transition || props.transition,
className: parseClassName(options.className || props.toastClassName),
bodyClassName: parseClassName(options.bodyClassName || props.bodyClassName),
style: options.style || props.toastStyle,
bodyStyle: options.bodyStyle || props.bodyStyle,
onClick: options.onClick || props.onClick,
pauseOnHover: isBool(options.pauseOnHover) ? options.pauseOnHover : props.pauseOnHover,
pauseOnFocusLoss: isBool(options.pauseOnFocusLoss) ? options.pauseOnFocusLoss : props.pauseOnFocusLoss,
draggable: isBool(options.draggable) ? options.draggable : props.draggable,
draggablePercent: isNum(options.draggablePercent) ? options.draggablePercent : props.draggablePercent,
draggableDirection: options.draggableDirection || props.draggableDirection,
closeOnClick: isBool(options.closeOnClick) ? options.closeOnClick : props.closeOnClick,
progressClassName: parseClassName(options.progressClassName || props.progressClassName),
progressStyle: options.progressStyle || props.progressStyle,
autoClose: getAutoCloseDelay(options.autoClose, props.autoClose),
hideProgressBar: isBool(options.hideProgressBar) ? options.hideProgressBar : props.hideProgressBar,
progress: options.progress,
role: isStr(options.role) ? options.role : props.role,
deleteToast: function deleteToast() {
removeFromCollection(toastId);
}
};
if (isFn(options.onOpen)) toastProps.onOpen = options.onOpen;
if (isFn(options.onClose)) toastProps.onClose = options.onClose; // tweak for vertical dragging
if (toastProps.draggableDirection === "y"
/* Y */
&& toastProps.draggablePercent === 80
/* DRAGGABLE_PERCENT */
) {
toastProps.draggablePercent *= 1.5;
}
var closeButton = props.closeButton;
if (options.closeButton === false || canBeRendered(options.closeButton)) {
closeButton = options.closeButton;
} else if (options.closeButton === true) {
closeButton = canBeRendered(props.closeButton) ? props.closeButton : true;
}
toastProps.closeButton = closeButton;
var toastContent = content;
if (isValidElement(content) && !isStr(content.type)) {
toastContent = cloneElement(content, {
closeToast: closeToast,
toastProps: toastProps
});
} else if (isFn(content)) {
toastContent = content({
closeToast: closeToast,
toastProps: toastProps
});
} // not handling limit + delay by design. Waiting for user feedback first
if (props.limit && props.limit > 0 && toastCount > props.limit && isNotAnUpdate) {
queue.push({
toastContent: toastContent,
toastProps: toastProps,
staleId: staleId
});
} else if (isNum(delay) && delay > 0) {
setTimeout(function () {
appendToast(toastContent, toastProps, staleId);
}, delay);
} else {
appendToast(toastContent, toastProps, staleId);
}
}
function appendToast(content, toastProps, staleId) {
var toastId = toastProps.toastId;
if (staleId) delete collection[staleId];
collection[toastId] = {
content: content,
props: toastProps
};
dispatch({
type: 0
/* ADD */
,
toastId: toastId,
staleId: staleId
});
}
function removeFromCollection(toastId) {
delete collection[toastId];
var queueLen = queue.length;
toastCount = isToastIdValid(toastId) ? toastCount - 1 : toastCount - instance.displayedToast;
if (toastCount < 0) toastCount = 0;
if (queueLen > 0) {
var freeSlot = isToastIdValid(toastId) ? 1 : instance.props.limit;
if (queueLen === 1 || freeSlot === 1) {
instance.displayedToast++;
dequeueToast();
} else {
var toDequeue = freeSlot > queueLen ? queueLen : freeSlot;
instance.displayedToast = toDequeue;
for (var i = 0; i < toDequeue; i++) {
dequeueToast();
}
}
} else {
forceUpdate();
}
}
function getToastToRender(cb) {
var toastToRender = {};
var toastList = props.newestOnTop ? Object.keys(collection).reverse() : Object.keys(collection);
for (var i = 0; i < toastList.length; i++) {
var _toast = collection[toastList[i]];
var position = _toast.props.position;
toastToRender[position] || (toastToRender[position] = []);
toastToRender[position].push(_toast);
}
return Object.keys(toastToRender).map(function (p) {
return cb(p, toastToRender[p]);
});
}
return {
getToastToRender: getToastToRender,
collection: collection,
containerRef: containerRef,
isToastActive: isToastActive
};
}
function getX(e) {
return e.targetTouches && e.targetTouches.length >= 1 ? e.targetTouches[0].clientX : e.clientX;
}
function getY(e) {
return e.targetTouches && e.targetTouches.length >= 1 ? e.targetTouches[0].clientY : e.clientY;
}
function useToast(props) {
var _useState = useState(true),
isRunning = _useState[0],
setIsRunning = _useState[1];
var _useState2 = useState(false),
preventExitTransition = _useState2[0],
setPreventExitTransition = _useState2[1];
var toastRef = useRef(null);
var drag = useKeeper({
start: 0,
x: 0,
y: 0,
delta: 0,
removalDistance: 0,
canCloseOnClick: true,
canDrag: false,
boundingRect: null
});
var syncProps = useKeeper(props, true);
var autoClose = props.autoClose,
pauseOnHover = props.pauseOnHover,
closeToast = props.closeToast,
onClick = props.onClick,
closeOnClick = props.closeOnClick;
useEffect(function () {
if (isFn(props.onOpen)) props.onOpen(isValidElement(props.children) && props.children.props);
return function () {
if (isFn(syncProps.onClose)) syncProps.onClose(isValidElement(syncProps.children) && syncProps.children.props);
};
}, []);
useEffect(function () {
props.draggable && bindDragEvents();
return function () {
props.draggable && unbindDragEvents();
};
}, [props.draggable]);
useEffect(function () {
props.pauseOnFocusLoss && bindFocusEvents();
return function () {
props.pauseOnFocusLoss && unbindFocusEvents();
};
}, [props.pauseOnFocusLoss]);
function onDragStart(e) {
if (props.draggable) {
var toast = toastRef.current;
drag.canCloseOnClick = true;
drag.canDrag = true;
drag.boundingRect = toast.getBoundingClientRect();
toast.style.transition = '';
drag.x = getX(e.nativeEvent);
drag.y = getY(e.nativeEvent);
if (props.draggableDirection === "x"
/* X */
) {
drag.start = drag.x;
drag.removalDistance = toast.offsetWidth * (props.draggablePercent / 100);
} else {
drag.start = drag.y;
drag.removalDistance = toast.offsetHeight * (props.draggablePercent / 100);
}
}
}
function onDragTransitionEnd() {
if (drag.boundingRect) {
var _drag$boundingRect = drag.boundingRect,
top = _drag$boundingRect.top,
bottom = _drag$boundingRect.bottom,
left = _drag$boundingRect.left,
right = _drag$boundingRect.right;
if (props.pauseOnHover && drag.x >= left && drag.x <= right && drag.y >= top && drag.y <= bottom) {
pauseToast();
} else {
playToast();
}
}
}
function playToast() {
setIsRunning(true);
}
function pauseToast() {
setIsRunning(false);
}
function bindFocusEvents() {
if (!document.hasFocus()) pauseToast();
window.addEventListener('focus', playToast);
window.addEventListener('blur', pauseToast);
}
function unbindFocusEvents() {
window.removeEventListener('focus', playToast);
window.removeEventListener('blur', pauseToast);
}
function bindDragEvents() {
document.addEventListener('mousemove', onDragMove);
document.addEventListener('mouseup', onDragEnd);
document.addEventListener('touchmove', onDragMove);
document.addEventListener('touchend', onDragEnd);
}
function unbindDragEvents() {
document.removeEventListener('mousemove', onDragMove);
document.removeEventListener('mouseup', onDragEnd);
document.removeEventListener('touchmove', onDragMove);
document.removeEventListener('touchend', onDragEnd);
}
function onDragMove(e) {
if (drag.canDrag) {
e.preventDefault();
var toast = toastRef.current;
if (isRunning) pauseToast();
drag.x = getX(e);
drag.y = getY(e);
if (props.draggableDirection === "x"
/* X */
) {
drag.delta = drag.x - drag.start;
} else {
drag.delta = drag.y - drag.start;
} // prevent false positif during a toast click
if (drag.start !== drag.x) drag.canCloseOnClick = false;
toast.style.transform = "translate" + props.draggableDirection + "(" + drag.delta + "px)";
toast.style.opacity = "" + (1 - Math.abs(drag.delta / drag.removalDistance));
}
}
function onDragEnd() {
var toast = toastRef.current;
if (drag.canDrag) {
drag.canDrag = false;
if (Math.abs(drag.delta) > drag.removalDistance) {
setPreventExitTransition(true);
props.closeToast();
return;
}
toast.style.transition = 'transform 0.2s, opacity 0.2s';
toast.style.transform = "translate" + props.draggableDirection + "(0)";
toast.style.opacity = '1';
}
}
var eventHandlers = {
onMouseDown: onDragStart,
onTouchStart: onDragStart,
onMouseUp: onDragTransitionEnd,
onTouchEnd: onDragTransitionEnd
};
if (autoClose && pauseOnHover) {
eventHandlers.onMouseEnter = pauseToast;
eventHandlers.onMouseLeave = playToast;
} // prevent toast from closing when user drags the toast
if (closeOnClick) {
eventHandlers.onClick = function (e) {
onClick && onClick(e);
drag.canCloseOnClick && closeToast();
};
}
return {
playToast: playToast,
pauseToast: pauseToast,
isRunning: isRunning,
preventExitTransition: preventExitTransition,
toastRef: toastRef,
eventHandlers: eventHandlers
};
}
function CloseButton(_ref) {
var closeToast = _ref.closeToast,
type = _ref.type,
_ref$ariaLabel = _ref.ariaLabel,
ariaLabel = _ref$ariaLabel === void 0 ? 'close' : _ref$ariaLabel;
return createElement("button", {
className: "Toastify"
/* CSS_NAMESPACE */
+ "__close-button " + "Toastify"
/* CSS_NAMESPACE */
+ "__close-button--" + type,
type: "button",
onClick: function onClick(e) {
e.stopPropagation();
closeToast(e);
},
"aria-label": ariaLabel
}, createElement("svg", {
"aria-hidden": "true",
viewBox: "0 0 14 16"
}, createElement("path", {
fillRule: "evenodd",
d: "M7.71 8.23l3.75 3.75-1.48 1.48-3.75-3.75-3.75 3.75L1 11.98l3.75-3.75L1 4.48 2.48 3l3.75 3.75L9.98 3l1.48 1.48-3.75 3.75z"
})));
}
function ProgressBar(_ref) {
var _cx, _animationEvent;
var delay = _ref.delay,
isRunning = _ref.isRunning,
closeToast = _ref.closeToast,
type = _ref.type,
hide = _ref.hide,
className = _ref.className,
userStyle = _ref.style,
controlledProgress = _ref.controlledProgress,
progress = _ref.progress,
rtl = _ref.rtl,
isIn = _ref.isIn;
var style = _extends({}, userStyle, {
animationDuration: delay + "ms",
animationPlayState: isRunning ? 'running' : 'paused',
opacity: hide ? 0 : 1
});
if (controlledProgress) style.transform = "scaleX(" + progress + ")";
var defaultClassName = cx("Toastify"
/* CSS_NAMESPACE */
+ "__progress-bar", controlledProgress ? "Toastify"
/* CSS_NAMESPACE */
+ "__progress-bar--controlled" : "Toastify"
/* CSS_NAMESPACE */
+ "__progress-bar--animated", "Toastify"
/* CSS_NAMESPACE */
+ "__progress-bar--" + type, (_cx = {}, _cx["Toastify"
/* CSS_NAMESPACE */
+ "__progress-bar--rtl"] = rtl, _cx));
var classNames = isFn(className) ? className({
rtl: rtl,
type: type,
defaultClassName: defaultClassName
}) : cx(defaultClassName, className); // 🧐 controlledProgress is derived from progress
// so if controlledProgress is set
// it means that this is also the case for progress
var animationEvent = (_animationEvent = {}, _animationEvent[controlledProgress && progress >= 1 ? 'onTransitionEnd' : 'onAnimationEnd'] = controlledProgress && progress < 1 ? null : function () {
isIn && closeToast();
}, _animationEvent); // TODO: add aria-valuenow, aria-valuemax, aria-valuemin
return createElement("div", Object.assign({
role: "progressbar",
"aria-hidden": hide ? 'true' : 'false',
"aria-label": "notification timer",
className: classNames,
style: style
}, animationEvent));
}
ProgressBar.defaultProps = {
type: TYPE.DEFAULT,
hide: false
};
var Toast = function Toast(props) {
var _cx;
var _useToast = useToast(props),
isRunning = _useToast.isRunning,
preventExitTransition = _useToast.preventExitTransition,
toastRef = _useToast.toastRef,
eventHandlers = _useToast.eventHandlers;
var closeButton = props.closeButton,
children = props.children,
autoClose = props.autoClose,
onClick = props.onClick,
type = props.type,
hideProgressBar = props.hideProgressBar,
closeToast = props.closeToast,
Transition = props.transition,
position = props.position,
className = props.className,
style = props.style,
bodyClassName = props.bodyClassName,
bodyStyle = props.bodyStyle,
progressClassName = props.progressClassName,
progressStyle = props.progressStyle,
updateId = props.updateId,
role = props.role,
progress = props.progress,
rtl = props.rtl,
toastId = props.toastId,
deleteToast = props.deleteToast,
isIn = props.isIn;
var defaultClassName = cx("Toastify"
/* CSS_NAMESPACE */
+ "__toast", "Toastify"
/* CSS_NAMESPACE */
+ "__toast--" + type, (_cx = {}, _cx["Toastify"
/* CSS_NAMESPACE */
+ "__toast--rtl"] = rtl, _cx));
var cssClasses = isFn(className) ? className({
rtl: rtl,
position: position,
type: type,
defaultClassName: defaultClassName
}) : cx(defaultClassName, className);
var isProgressControlled = !!progress;
function renderCloseButton(closeButton) {
if (!closeButton) return;
var props = {
closeToast: closeToast,
type: type
};
if (isFn(closeButton)) return closeButton(props);
if (isValidElement(closeButton)) return cloneElement(closeButton, props);
}
return createElement(Transition, {
isIn: isIn,
done: deleteToast,
position: position,
preventExitTransition: preventExitTransition,
nodeRef: toastRef
}, createElement("div", Object.assign({
id: toastId,
onClick: onClick,
className: cssClasses
}, eventHandlers, {
style: style,
ref: toastRef
}), createElement("div", Object.assign({}, isIn && {
role: role
}, {
className: isFn(bodyClassName) ? bodyClassName({
type: type
}) : cx("Toastify"
/* CSS_NAMESPACE */
+ "__toast-body", bodyClassName),
style: bodyStyle
}), children), renderCloseButton(closeButton), (autoClose || isProgressControlled) && createElement(ProgressBar, Object.assign({}, updateId && !isProgressControlled ? {
key: "pb-" + updateId
} : {}, {
rtl: rtl,
delay: autoClose,
isRunning: isRunning,
isIn: isIn,
closeToast: closeToast,
hide: hideProgressBar,
type: type,
style: progressStyle,
className: progressClassName,
controlledProgress: isProgressControlled,
progress: progress
}))));
};
var Bounce = /*#__PURE__*/cssTransition({
enter: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__bounce-enter",
exit: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__bounce-exit",
appendPosition: true
});
var Slide = /*#__PURE__*/cssTransition({
enter: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__slide-enter",
exit: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__slide-exit",
appendPosition: true
});
var Zoom = /*#__PURE__*/cssTransition({
enter: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__zoom-enter",
exit: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__zoom-exit"
});
var Flip = /*#__PURE__*/cssTransition({
enter: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__flip-enter",
exit: "Toastify"
/* CSS_NAMESPACE */
+ "--animate " + "Toastify"
/* CSS_NAMESPACE */
+ "__flip-exit"
});
var ToastContainer = function ToastContainer(props) {
var _useToastContainer = useToastContainer(props),
getToastToRender = _useToastContainer.getToastToRender,
containerRef = _useToastContainer.containerRef,
isToastActive = _useToastContainer.isToastActive;
var className = props.className,
style = props.style,
rtl = props.rtl,
containerId = props.containerId;
function getClassName(position) {
var _cx;
var defaultClassName = cx("Toastify"
/* CSS_NAMESPACE */
+ "__toast-container", "Toastify"
/* CSS_NAMESPACE */
+ "__toast-container--" + position, (_cx = {}, _cx["Toastify"
/* CSS_NAMESPACE */
+ "__toast-container--rtl"] = rtl, _cx));
return isFn(className) ? className({
position: position,
rtl: rtl,
defaultClassName: defaultClassName
}) : cx(defaultClassName, parseClassName(className));
}
return createElement("div", {
ref: containerRef,
className: "Toastify"
/* CSS_NAMESPACE */
,
id: containerId
}, getToastToRender(function (position, toastList) {
var containerStyle = toastList.length === 0 ? _extends({}, style, {
pointerEvents: 'none'
}) : _extends({}, style);
return createElement("div", {
className: getClassName(position),
style: containerStyle,
key: "container-" + position
}, toastList.map(function (_ref) {
var content = _ref.content,
toastProps = _ref.props;
return createElement(Toast, Object.assign({}, toastProps, {
isIn: isToastActive(toastProps.toastId),
key: "toast-" + toastProps.key,
closeButton: toastProps.closeButton === true ? CloseButton : toastProps.closeButton
}), content);
}));
}));
};
ToastContainer.defaultProps = {
position: POSITION.TOP_RIGHT,
transition: Bounce,
rtl: false,
autoClose: 5000,
hideProgressBar: false,
closeButton: CloseButton,
pauseOnHover: true,
pauseOnFocusLoss: true,
closeOnClick: true,
newestOnTop: false,
draggable: true,
draggablePercent: 80
/* DRAGGABLE_PERCENT */
,
draggableDirection: "x"
/* X */
,
role: 'alert'
};
var containers = /*#__PURE__*/new Map();
var latestInstance;
var containerDomNode;
var containerConfig;
var queue = [];
var lazy = false;
/**
* Check whether any container is currently mounted in the DOM
*/
function isAnyContainerMounted() {
return containers.size > 0;
}
/**
* Get the toast by id, given it's in the DOM, otherwise returns null
*/
function getToast(toastId, _ref) {
var containerId = _ref.containerId;
var container = containers.get(containerId || latestInstance);
if (!container) return null;
return container.getToast(toastId);
}
/**
* Generate a random toastId
*/
function generateToastId() {
return Math.random().toString(36).substr(2, 9);
}
/**
* Generate a toastId or use the one provided
*/
function getToastId(options) {
if (options && (isStr(options.toastId) || isNum(options.toastId))) {
return options.toastId;
}
return generateToastId();
}
/**
* If the container is not mounted, the toast is enqueued and
* the container lazy mounted
*/
function dispatchToast(content, options) {
if (isAnyContainerMounted()) {
eventManager.emit(0
/* Show */
, content, options);
} else {
queue.push({
content: content,
options: options
});
if (lazy && canUseDom) {
lazy = false;
containerDomNode = document.createElement('div');
document.body.appendChild(containerDomNode);
render(createElement(ToastContainer, Object.assign({}, containerConfig)), containerDomNode);
}
}
return options.toastId;
}
/**
* Merge provided options with the defaults settings and generate the toastId
*/
function mergeOptions(type, options) {
return _extends({}, options, {
type: options && options.type || type,
toastId: getToastId(options)
});
}
var createToastByType = function createToastByType(type) {
return function (content, options) {
return dispatchToast(content, mergeOptions(type, options));
};
};
var toast = function toast(content, options) {
return dispatchToast(content, mergeOptions(TYPE.DEFAULT, options));
};
toast.success = /*#__PURE__*/createToastByType(TYPE.SUCCESS);
toast.info = /*#__PURE__*/createToastByType(TYPE.INFO);
toast.error = /*#__PURE__*/createToastByType(TYPE.ERROR);
toast.warning = /*#__PURE__*/createToastByType(TYPE.WARNING);
toast.dark = /*#__PURE__*/createToastByType(TYPE.DARK);
toast.warn = toast.warning;
/**
* Remove toast programmaticaly
*/
toast.dismiss = function (id) {
return eventManager.emit(1
/* Clear */
, id);
};
/**
* Clear waiting queue when limit is used
*/
toast.clearWaitingQueue = function (params) {
if (params === void 0) {
params = {};
}
return eventManager.emit(5
/* ClearWaitingQueue */
, params);
};
/**
* return true if one container is displaying the toast
*/
toast.isActive = function (id) {
var isToastActive = false;
containers.forEach(function (container) {
if (container.isToastActive && container.isToastActive(id)) {
isToastActive = true;
}
});
return isToastActive;
};
toast.update = function (toastId, options) {
if (options === void 0) {
options = {};
}
// if you call toast and toast.update directly nothing will be displayed
// this is why I defered the update
setTimeout(function () {
var toast = getToast(toastId, options);
if (toast) {
var oldOptions = toast.props,
oldContent = toast.content;
var nextOptions = _extends({}, oldOptions, options, {
toastId: options.toastId || toastId,
updateId: generateToastId()
});
if (nextOptions.toastId !== toastId) nextOptions.staleId = toastId;
var content = nextOptions.render || oldContent;
delete nextOptions.render;
dispatchToast(content, nextOptions);
}
}, 0);
};
/**
* Used for controlled progress bar.
*/
toast.done = function (id) {
toast.update(id, {
progress: 1
});
};
/**
* Track changes. The callback get the number of toast displayed
*
*/
toast.onChange = function (callback) {
if (isFn(callback)) {
eventManager.on(4
/* Change */
, callback);
}
return function () {
isFn(callback) && eventManager.off(4
/* Change */
, callback);
};
};
/**
* Configure the ToastContainer when lazy mounted
*/
toast.configure = function (config) {
if (config === void 0) {
config = {};
}
lazy = true;
containerConfig = config;
};
toast.POSITION = POSITION;
toast.TYPE = TYPE;
/**
* Wait until the ToastContainer is mounted to dispatch the toast
* and attach isActive method
*/
eventManager.on(2
/* DidMount */
, function (containerInstance) {
latestInstance = containerInstance.containerId || containerInstance;
containers.set(latestInstance, containerInstance);
queue.forEach(function (item) {
eventManager.emit(0
/* Show */
, item.content, item.options);
});
queue = [];
}).on(3
/* WillUnmount */
, function (containerInstance) {
containers["delete"](containerInstance.containerId || containerInstance);
if (containers.size === 0) {
eventManager.off(0
/* Show */
).off(1
/* Clear */
).off(5
/* ClearWaitingQueue */
);
}
if (canUseDom && containerDomNode) {
document.body.removeChild(containerDomNode);
}
});
export { Bounce, Flip, Slide, ToastContainer, Zoom, collapseToast, cssTransition, toast, useToast, useToastContainer };
//# sourceMappingURL=react-toastify.esm.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
export {};
@@ -0,0 +1 @@
export {};
@@ -0,0 +1 @@
export {};
@@ -0,0 +1 @@
export {};
@@ -0,0 +1 @@
export {};
+1
View File
@@ -0,0 +1 @@
export {};
+9
View File
@@ -0,0 +1,9 @@
export declare const cssClasses: {
rtl: string;
progressBar: string;
progressBarController: string;
closeButton: string;
container: string;
};
export declare function triggerAnimationEnd(node: HTMLElement | HTMLElement[]): void;
export declare function waitForUseEffectCleanup(fn: () => void): void;
@@ -0,0 +1 @@
export {};
@@ -0,0 +1 @@
export {};
@@ -0,0 +1 @@
export {};
+240
View File
@@ -0,0 +1,240 @@
import * as React from 'react';
declare type Nullable<T> = {
[P in keyof T]: T[P] | null;
};
export declare type TypeOptions = 'info' | 'success' | 'warning' | 'error' | 'default' | 'dark';
export declare type ToastPosition = 'top-right' | 'top-center' | 'top-left' | 'bottom-right' | 'bottom-center' | 'bottom-left';
export interface ToastContentProps {
closeToast?: () => void;
toastProps: ToastProps;
}
export declare type ToastContent = React.ReactNode | ((props: ToastContentProps) => React.ReactNode);
export interface Toast {
content: ToastContent;
props: ToastProps;
}
export declare type Id = number | string;
export declare type ToastTransition = React.FC<ToastTransitionProps> | React.ComponentClass<ToastTransitionProps>;
/**
* ClassName for the elements - can take a function to build a classname or a raw string that is cx'ed to defaults
*/
export declare type ClassName = ((context?: {
defaultClassName?: string;
position?: ToastPosition;
rtl?: boolean;
}) => string) | string;
export declare type ToastClassName = ((context?: {
type?: TypeOptions;
defaultClassName?: string;
position?: ToastPosition;
rtl?: boolean;
}) => string) | string;
export interface ClearWaitingQueueParams {
containerId?: Id;
}
export declare type DraggableDirection = 'x' | 'y';
interface CommonOptions {
/**
* Pause the timer when the mouse hover the toast.
* `Default: true`
*/
pauseOnHover?: boolean;
/**
* Pause the toast when the window loose focus.
* `Default: true`
*/
pauseOnFocusLoss?: boolean;
/**
* Remove the toast when clicked.
* `Default: true`
*/
closeOnClick?: boolean;
/**
* Set the delay in ms to close the toast automatically.
* Use `false` to prevent the toast from closing.
* `Default: 5000`
*/
autoClose?: number | false;
/**
* Set the default position to use.
* `One of: 'top-right', 'top-center', 'top-left', 'bottom-right', 'bottom-center', 'bottom-left'`
* `Default: 'top-right'`
*/
position?: ToastPosition;
/**
* Pass a custom close button.
* To remove the close button pass `false`
*/
closeButton?: React.ReactElement | ((props: any) => React.ReactElement) | boolean;
/**
* An optional css class to set for the progress bar.
*/
progressClassName?: ToastClassName;
/**
* An optional style to set for the progress bar.
*/
progressStyle?: React.CSSProperties;
/**
* An optional css class to set for the toast content.
*/
bodyClassName?: ToastClassName;
/**
* An optional inline style to apply for the toast content.
*/
bodyStyle?: React.CSSProperties;
/**
* Hide or show the progress bar.
* `Default: false`
*/
hideProgressBar?: boolean;
/**
* Pass a custom transition built with react-transition-group.
*/
transition?: ToastTransition;
/**
* Allow toast to be draggable
* `Default: true`
*/
draggable?: boolean;
/**
* The percentage of the toast's width it takes for a drag to dismiss a toast
* `Default: 80`
*/
draggablePercent?: number;
/**
* Specify in which direction should you swipe to dismiss the toast
* `Default: "x"`
*/
draggableDirection?: DraggableDirection;
/**
* Define the ARIA role for the toast
* `Default: alert`
* https://www.w3.org/WAI/PF/aria/roles
*/
role?: string;
/**
* Set id to handle multiple container
*/
containerId?: Id;
/**
* Fired when clicking inside toaster
*/
onClick?: (event: React.MouseEvent) => void;
/**
* Support right to left display.
* `Default: false`
*/
rtl?: boolean;
}
export interface ToastOptions extends CommonOptions {
/**
* An optional css class to set.
*/
className?: ToastClassName;
/**
* Called when toast is mounted.
*/
onOpen?: <T = {}>(props: T) => void;
/**
* Called when toast is unmounted.
*/
onClose?: <T = {}>(props: T) => void;
/**
* An optional inline style to apply.
*/
style?: React.CSSProperties;
/**
* Set the toast type.
* `One of: 'info', 'success', 'warning', 'error', 'default'`
*/
type?: TypeOptions;
/**
* Set a custom `toastId`
*/
toastId?: Id;
/**
* Used during update
*/
updateId?: Id;
/**
* Set the percentage for the controlled progress bar. `Value must be between 0 and 1.`
*/
progress?: number | string;
/**
* Add a delay in ms before the toast appear.
*/
delay?: number;
}
/**
* @INTERNAL
*/
export interface ToastProps extends ToastOptions {
isIn: boolean;
staleId?: Id;
toastId: Id;
key: Id;
transition: ToastTransition;
closeToast: () => void;
position: ToastPosition;
children?: ToastContent;
draggablePercent: number;
draggableDirection?: DraggableDirection;
progressClassName?: ToastClassName;
className?: ToastClassName;
bodyClassName?: ToastClassName;
deleteToast: () => void;
}
/**
* @INTERNAL
*/
export interface NotValidatedToastProps extends Partial<ToastProps> {
toastId: Id;
}
export interface UpdateOptions extends Nullable<ToastOptions> {
/**
* Used to update a toast.
* Pass any valid ReactNode(string, number, component)
*/
render?: ToastContent;
}
export interface ToastContainerProps extends CommonOptions {
/**
* An optional css class to set.
*/
className?: ClassName;
/**
* Whether or not to display the newest toast on top.
* `Default: false`
*/
newestOnTop?: boolean;
/**
* An optional inline style to apply.
*/
style?: React.CSSProperties;
/**
* An optional inline style to apply for the toast.
*/
toastStyle?: React.CSSProperties;
/**
* An optional css class for the toast.
*/
toastClassName?: ToastClassName;
/**
* Show the toast only if it includes containerId and it's the same as containerId
* `Default: false`
*/
enableMultiContainer?: boolean;
/**
* Limit the number of toast displayed at the same time
*/
limit?: number;
}
export interface ToastTransitionProps {
isIn: boolean;
done: () => void;
position: ToastPosition | string;
preventExitTransition: boolean;
nodeRef: React.RefObject<HTMLElement>;
children?: React.ReactNode;
}
export {};
+5
View File
@@ -0,0 +1,5 @@
import { Default } from './constant';
/**
* Used to collapse toast after exit animation
*/
export declare function collapseToast(node: HTMLElement, done: () => void, duration?: Default): void;
+20
View File
@@ -0,0 +1,20 @@
import { ToastPosition, TypeOptions } from '../types';
declare type KeyOfPosition = 'TOP_LEFT' | 'TOP_RIGHT' | 'TOP_CENTER' | 'BOTTOM_LEFT' | 'BOTTOM_RIGHT' | 'BOTTOM_CENTER';
declare type KeyOfType = 'INFO' | 'SUCCESS' | 'WARNING' | 'ERROR' | 'DEFAULT' | 'DARK';
export declare const POSITION: {
[key in KeyOfPosition]: ToastPosition;
};
export declare const TYPE: {
[key in KeyOfType]: TypeOptions;
};
export declare const enum Default {
COLLAPSE_DURATION = 300,
DEBOUNCE_DURATION = 50,
CSS_NAMESPACE = "Toastify",
DRAGGABLE_PERCENT = 80
}
export declare const enum Direction {
X = "x",
Y = "y"
}
export {};
+42
View File
@@ -0,0 +1,42 @@
import { ToastTransitionProps } from '../types';
export interface CSSTransitionProps {
/**
* Css class to apply when toast enter
*/
enter: string;
/**
* Css class to apply when toast leave
*/
exit: string;
/**
* Append current toast position to the classname.
* If multiple classes are provided, only the last one will get the position
* For instance `myclass--top-center`...
* `Default: false`
*/
appendPosition?: boolean;
/**
* Collapse toast smoothly when exit animation end
* `Default: true`
*/
collapse?: boolean;
/**
* Collapse transition duration
* `Default: 300`
*/
collapseDuration?: number;
}
/**
* Css animation that just work.
* You could use animate.css for instance
*
*
* ```
* cssTransition({
* enter: "animate__animated animate__bounceIn",
* exit: "animate__animated animate__bounceOut"
* })
* ```
*
*/
export declare function cssTransition({ enter, exit, appendPosition, collapse, collapseDuration }: CSSTransitionProps): ({ children, position, preventExitTransition, done, nodeRef, isIn }: ToastTransitionProps) => JSX.Element;
+4
View File
@@ -0,0 +1,4 @@
export * from './propValidator';
export * from './constant';
export * from './cssTransition';
export * from './collapseToast';
+10
View File
@@ -0,0 +1,10 @@
import { Id } from '../types';
export declare function isNum(v: any): v is Number;
export declare function isBool(v: any): v is Boolean;
export declare function isStr(v: any): v is String;
export declare function isFn(v: any): v is Function;
export declare function parseClassName(v: any): any;
export declare function isToastIdValid(toastId?: Id): string | number | true | undefined;
export declare function getAutoCloseDelay(toastAutoClose?: false | number, containerAutoClose?: false | number): number | false | undefined;
export declare const canUseDom: boolean;
export declare function canBeRendered<T>(content: T): boolean;
+99
View File
@@ -0,0 +1,99 @@
{
"version": "7.0.4",
"license": "MIT",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"description": "React notification made easy",
"keywords": [
"react",
"notification",
"toast",
"react-component",
"react-toastify",
"push",
"alert"
],
"files": [
"dist",
"scss"
],
"sideEffects": [
"*.css"
],
"scripts": {
"start": "cd example && npm run start",
"build": "npm run prepare",
"test": "tsdx test --passWithNoTests",
"test:coverage": "tsdx test --coverage",
"lint": "tsdx lint src",
"prepare": "tsdx build && npm run style",
"sass": "sass scss/main.scss dist/ReactToastify.css",
"sass-minimal": "sass scss/minimal.scss dist/ReactToastify.minimal.css",
"postsass": "postcss dist/ReactToastify.css --use autoprefixer -m -o dist/ReactToastify.css",
"postsass-minimal": "cssnano dist/ReactToastify.minimal.css dist/ReactToastify.minimal.css --no-zindex --no-reduceIdents",
"style": "npm run sass && npm run sass-minimal && cssnano dist/ReactToastify.css dist/ReactToastify.min.css --no-zindex --no-reduceIdents && npm run style-injector",
"style-injector": "style2js --out-dir dist dist/ReactToastify.min.css"
},
"peerDependencies": {
"react": ">=16",
"react-dom": ">=16"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint"
}
},
"prettier": {
"printWidth": 80,
"semi": true,
"singleQuote": true
},
"eslint": {
"rules": {
"react-hooks/exhaustive-deps": "warn"
}
},
"jest": {
"verbose": true,
"coveragePathIgnorePatterns": [
"/src/index.tsx"
]
},
"name": "react-toastify",
"repository": {
"type": "git",
"url": "git+https://github.com/fkhadra/react-toastify.git"
},
"author": "Fadi Khadra <fdkhadra@gmail.com> (https://fkhadra.github.io)",
"bugs": {
"url": "https://github.com/fkhadra/react-toastify/issues"
},
"homepage": "https://github.com/fkhadra/react-toastify#readme",
"module": "dist/react-toastify.esm.js",
"devDependencies": {
"@babel/core": "^7.0.0-0",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/preset-env": "^7.8.4",
"@babel/preset-react": "^7.8.3",
"@testing-library/react": "^9.4.0",
"@types/jest": "^24.9.0",
"@types/react": "^16.9.34",
"@types/react-dom": "^16.9.6",
"coveralls": "^3.0.9",
"cssnano": "^4.1.10",
"cssnano-cli": "^1.0.5",
"husky": "^4.2.0",
"postcss": "^7.0.27",
"postcss-cli": "^7.1.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"sass": "^1.26.0",
"style2js": "^1.0.0",
"tsdx": "^0.12.3",
"tslib": "^1.10.0",
"typescript": "^3.7.5"
},
"dependencies": {
"clsx": "^1.1.1"
}
}
+26
View File
@@ -0,0 +1,26 @@
.#{$rt-namespace}__close-button {
color: #fff;
background: transparent;
outline: none;
border: none;
padding: 0;
cursor: pointer;
opacity: 0.7;
transition: 0.3s ease;
align-self: flex-start;
&--default {
color: #000;
opacity: 0.3;
}
& > svg {
fill: currentColor;
height: 16px;
width: 14px;
}
&:hover, &:focus {
opacity: 1;
}
}
+47
View File
@@ -0,0 +1,47 @@
@keyframes #{$rt-namespace}__trackProgress {
0%{
transform: scaleX(1);
}
100%{
transform: scaleX(0);
}
}
.#{$rt-namespace}__progress-bar {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 5px;
z-index: $rt-z-index;
opacity: 0.7;
background-color: rgba(255,255,255,.7);
transform-origin: left;
&--animated {
animation: #{$rt-namespace}__trackProgress linear 1 forwards;
}
&--controlled {
transition: transform .2s;
}
&--rtl {
right: 0;
left: initial;
transform-origin: right;
}
&--default{
background: $rt-color-progress-default;
}
&--dark{
background: $rt-color-progress-dark;
}
&--info{}
&--success{}
&--warning{}
&--error{}
}
+56
View File
@@ -0,0 +1,56 @@
.#{$rt-namespace}__toast {
position: relative;
min-height: $rt-toast-min-height;
box-sizing: border-box;
margin-bottom: 1rem;
padding: 8px;
border-radius: 4px;
box-shadow: 0 1px 10px 0 rgba(0, 0, 0, 0.1), 0 2px 15px 0 rgba(0, 0, 0, 0.05);
display: flex;
justify-content: space-between;
max-height: $rt-toast-max-height;
overflow: hidden;
font-family: $rt-font-family;
cursor: pointer;
direction: ltr;
&--rtl {
direction: rtl;
}
&--dark {
background: $rt-color-dark;
color: $rt-text-color-dark;
}
&--default {
background: $rt-color-default;
color: $rt-text-color-default;
}
&--info {
background: $rt-color-info;
}
&--success {
background: $rt-color-success;
}
&--warning {
background: $rt-color-warning;
}
&--error {
background: $rt-color-error;
}
&-body {
margin: auto 0;
flex: 1 1 auto;
padding: 6px;
}
}
.#{$rt-namespace}--animate {
animation-fill-mode: both;
animation-duration: 0.7s;
}
@media #{$rt-mobile} {
.#{$rt-namespace}__toast {
margin-bottom: 0;
border-radius: 0;
}
}
+60
View File
@@ -0,0 +1,60 @@
.#{$rt-namespace}__toast-container {
z-index: $rt-z-index;
-webkit-transform: translate3d(0, 0, #{$rt-z-index}px);
position: fixed;
padding: 4px;
width: $rt-toast-width;
box-sizing: border-box;
color: #fff;
&--top-left {
top: 1em;
left: 1em;
}
&--top-center {
top: 1em;
left: 50%;
transform: translateX(-50%);
}
&--top-right {
top: 1em;
right: 1em;
}
&--bottom-left {
bottom: 1em;
left: 1em;
}
&--bottom-center {
bottom: 1em;
left: 50%;
transform: translateX(-50%);
}
&--bottom-right {
bottom: 1em;
right: 1em;
}
}
@media #{$rt-mobile} {
.#{$rt-namespace}__toast-container {
width: 100vw;
padding: 0;
left: 0;
margin: 0;
&--top-left,
&--top-center,
&--top-right {
top: 0;
transform: translateX(0);
}
&--bottom-left,
&--bottom-center,
&--bottom-right {
bottom: 0;
transform: translateX(0);
}
&--rtl{
right: 0;
left: initial;
}
}
}
+22
View File
@@ -0,0 +1,22 @@
$rt-namespace: 'Toastify';
$rt-toast-width: 320px !default;
$rt-toast-background: #fff !default;
$rt-toast-min-height: 64px !default;
$rt-toast-max-height: 800px !default;
$rt-color-default: #fff !default;
$rt-color-dark: #121212 !default;
$rt-color-info: #3498db !default;
$rt-color-success: #07bc0c !default;
$rt-color-warning: #f1c40f !default;
$rt-color-error: #e74c3c !default;
$rt-text-color-default: #aaa !default;
$rt-text-color-dark: #fff !default;
$rt-color-progress-default: linear-gradient(to right, #4cd964, #5ac8fa, #007aff, #34aadc, #5856d6, #ff2d55) !default;
$rt-color-progress-dark: #bb86fc !default;
$rt-mobile: "only screen and (max-width : 480px)" !default;
$rt-font-family: sans-serif !default;
$rt-z-index: 9999 !default;
+197
View File
@@ -0,0 +1,197 @@
@mixin timing-function {
animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
}
@keyframes #{$rt-namespace}__bounceInRight {
from,
60%,
75%,
90%,
to {
@include timing-function;
}
from {
opacity: 0;
transform: translate3d(3000px, 0, 0);
}
60% {
opacity: 1;
transform: translate3d(-25px, 0, 0);
}
75% {
transform: translate3d(10px, 0, 0);
}
90% {
transform: translate3d(-5px, 0, 0);
}
to {
transform: none;
}
}
@keyframes #{$rt-namespace}__bounceOutRight {
20% {
opacity: 1;
transform: translate3d(-20px, 0, 0);
}
to {
opacity: 0;
transform: translate3d(2000px, 0, 0);
}
}
@keyframes #{$rt-namespace}__bounceInLeft {
from,
60%,
75%,
90%,
to {
@include timing-function;
}
0% {
opacity: 0;
transform: translate3d(-3000px, 0, 0);
}
60% {
opacity: 1;
transform: translate3d(25px, 0, 0);
}
75% {
transform: translate3d(-10px, 0, 0);
}
90% {
transform: translate3d(5px, 0, 0);
}
to {
transform: none;
}
}
@keyframes #{$rt-namespace}__bounceOutLeft {
20% {
opacity: 1;
transform: translate3d(20px, 0, 0);
}
to {
opacity: 0;
transform: translate3d(-2000px, 0, 0);
}
}
@keyframes #{$rt-namespace}__bounceInUp {
from,
60%,
75%,
90%,
to {
@include timing-function;
}
from {
opacity: 0;
transform: translate3d(0, 3000px, 0);
}
60% {
opacity: 1;
transform: translate3d(0, -20px, 0);
}
75% {
transform: translate3d(0, 10px, 0);
}
90% {
transform: translate3d(0, -5px, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
@keyframes #{$rt-namespace}__bounceOutUp {
20% {
transform: translate3d(0, -10px, 0);
}
40%,
45% {
opacity: 1;
transform: translate3d(0, 20px, 0);
}
to {
opacity: 0;
transform: translate3d(0, -2000px, 0);
}
}
@keyframes #{$rt-namespace}__bounceInDown {
from,
60%,
75%,
90%,
to {
@include timing-function;
}
0% {
opacity: 0;
transform: translate3d(0, -3000px, 0);
}
60% {
opacity: 1;
transform: translate3d(0, 25px, 0);
}
75% {
transform: translate3d(0, -10px, 0);
}
90% {
transform: translate3d(0, 5px, 0);
}
to {
transform: none;
}
}
@keyframes #{$rt-namespace}__bounceOutDown {
20% {
transform: translate3d(0, 10px, 0);
}
40%,
45% {
opacity: 1;
transform: translate3d(0, -20px, 0);
}
to {
opacity: 0;
transform: translate3d(0, 2000px, 0);
}
}
.#{$rt-namespace}__bounce-enter {
&--top-left,
&--bottom-left {
animation-name: #{$rt-namespace}__bounceInLeft;
}
&--top-right,
&--bottom-right {
animation-name: #{$rt-namespace}__bounceInRight;
}
&--top-center {
animation-name: #{$rt-namespace}__bounceInDown;
}
&--bottom-center {
animation-name: #{$rt-namespace}__bounceInUp;
}
}
.#{$rt-namespace}__bounce-exit {
&--top-left,
&--bottom-left {
animation-name: #{$rt-namespace}__bounceOutLeft;
}
&--top-right,
&--bottom-right {
animation-name: #{$rt-namespace}__bounceOutRight;
}
&--top-center {
animation-name: #{$rt-namespace}__bounceOutUp;
}
&--bottom-center {
animation-name: #{$rt-namespace}__bounceOutDown;
}
}
+43
View File
@@ -0,0 +1,43 @@
@keyframes #{$rt-namespace}__flipIn {
from {
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
animation-timing-function: ease-in;
opacity: 0;
}
40% {
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
animation-timing-function: ease-in;
}
60% {
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
opacity: 1
}
80% {
transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
}
to {
transform: perspective(400px);
}
}
@keyframes #{$rt-namespace}__flipOut {
from {
transform: perspective(400px);
}
30% {
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
opacity: 1
}
to {
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
opacity: 0
}
}
.#{$rt-namespace}__flip-enter {
animation-name: #{$rt-namespace}__flipIn;
}
.#{$rt-namespace}__flip-exit {
animation-name: #{$rt-namespace}__flipOut;
}
+117
View File
@@ -0,0 +1,117 @@
@mixin transform {
transform: translate3d(0, 0, 0);
}
@keyframes #{$rt-namespace}__slideInRight {
from {
transform: translate3d(110%, 0, 0);
visibility: visible;
}
to {
@include transform;
}
}
@keyframes #{$rt-namespace}__slideInLeft {
from {
transform: translate3d(-110%, 0, 0);
visibility: visible;
}
to {
@include transform;
}
}
@keyframes #{$rt-namespace}__slideInUp {
from {
transform: translate3d(0, 110%, 0);
visibility: visible;
}
to {
@include transform;
}
}
@keyframes #{$rt-namespace}__slideInDown {
from {
transform: translate3d(0, -110%, 0);
visibility: visible;
}
to {
@include transform;
}
}
@keyframes #{$rt-namespace}__slideOutRight {
from {
@include transform;
}
to {
visibility: hidden;
transform: translate3d(110%, 0, 0);
}
}
@keyframes #{$rt-namespace}__slideOutLeft {
from {
@include transform;
}
to {
visibility: hidden;
transform: translate3d(-110%, 0, 0);
}
}
@keyframes #{$rt-namespace}__slideOutDown {
from {
@include transform;
}
to {
visibility: hidden;
transform: translate3d(0, 500px, 0);
}
}
@keyframes #{$rt-namespace}__slideOutUp {
from {
@include transform;
}
to {
visibility: hidden;
transform: translate3d(0, -500px, 0);
}
}
.#{$rt-namespace}__slide-enter {
&--top-left,
&--bottom-left {
animation-name: #{$rt-namespace}__slideInLeft;
}
&--top-right,
&--bottom-right {
animation-name: #{$rt-namespace}__slideInRight;
}
&--top-center {
animation-name: #{$rt-namespace}__slideInDown;
}
&--bottom-center {
animation-name: #{$rt-namespace}__slideInUp;
}
}
.#{$rt-namespace}__slide-exit {
&--top-left,
&--bottom-left {
animation-name: #{$rt-namespace}__slideOutLeft;
}
&--top-right,
&--bottom-right {
animation-name: #{$rt-namespace}__slideOutRight;
}
&--top-center {
animation-name: #{$rt-namespace}__slideOutUp;
}
&--bottom-center {
animation-name: #{$rt-namespace}__slideOutDown;
}
}
+30
View File
@@ -0,0 +1,30 @@
@keyframes #{$rt-namespace}__zoomIn {
from {
opacity: 0;
transform: scale3d(0.3, 0.3, 0.3);
}
50% {
opacity: 1;
}
}
@keyframes #{$rt-namespace}__zoomOut {
from {
opacity: 1;
}
50% {
opacity: 0;
transform: scale3d(0.3, 0.3, 0.3);
}
to {
opacity: 0
}
}
.#{$rt-namespace}__zoom-enter {
animation-name: #{$rt-namespace}__zoomIn;
}
.#{$rt-namespace}__zoom-exit {
animation-name: #{$rt-namespace}__zoomOut;
}
+13
View File
@@ -0,0 +1,13 @@
@charset "UTF-8";
@import "variables";
@import "toastContainer";
@import "toast";
@import "closeButton";
@import "progressBar";
// entrance and exit animations
@import "animations/bounce.scss";
@import "animations/zoom.scss";
@import "animations/flip.scss";
@import "animations/slide.scss";
+16
View File
@@ -0,0 +1,16 @@
@charset "UTF-8";
@import "variables";
@keyframes #{$rt-namespace}__trackProgress {
0%{
transform: scaleX(1);
}
100%{
transform: scaleX(0);
}
}
.#{$rt-namespace}__progress-bar {
animation: #{$rt-namespace}__trackProgress linear 1 forwards;
}