fkhadra / react-toastify

React notification made easy 🚀 !
https://fkhadra.github.io/react-toastify/introduction
MIT License
12.72k stars 700 forks source link

Style without css loader / global css #525

Closed net-bet closed 4 years ago

net-bet commented 4 years ago

Do you want to request a feature or report a bug? Feature What is the current behavior? If I am copying the css into the styled wrapper of the ToastContainer, the placement of the wrapper is relative to the container and not to the viewport.

Is there a possibility to allow the placement styling without the need to import the css?

fkhadra commented 4 years ago

Hello @net-bet ,

Can you describe your use case ?

Thanks

net-bet commented 4 years ago

Thanks for the response!

In order to give the basic styling I had to put some of the styles in the GlobalStyle (I took the css you distribute with the lib). I don't want it in the global style to prevent possibility for future collisions.

This is my component:

return ( <>

  <StyledToastContainer
    {...props}
    theme={theme}
  />
</>

This is StyledToastContainer:

const StyledToastContainer = styled(ToastContainer) &.Toastify__toast-container { } .Toastify__close-button { color: #000; } .Toastify__close-button > svg { width: 10px; height: 10px; } .Toastify__toast { border-radius: 6px; box-shadow: ${({ theme }) =>${theme.shadows.small} ${theme.palletes.dark}`}; min-height: auto; max-width: 500px; } .Toastifytoast { &--error { background-color: ${({ theme }) => theme.palletes.error[5]}; } &--warning{ background-color: ${({ theme }) => theme.palletes.warning[5]}; } &--success{ background-color: ${({ theme }) => theme.palletes.success[5]}; } &--info{ background-color: ${({ theme }) => theme.palletes.info[5]}; } } .Toastifytoast-body {} .Toastify__progress-bar { height: 3px;

&--error{
  background: ${({ theme }) => theme.palletes.error[0]};
}
&--info {
  background: ${({ theme }) => theme.palletes.info[0]};
}
&--success {
  background: ${({ theme }) => theme.palletes.success[0]};
}
&--warning {
  background: ${({ theme }) => theme.palletes.warning[0]};
}

} `;

This is GlobalStyle (If I move it from GlobalStyle to StyledToastContainer it doesn't work)

const GlobalStyle = createGlobalStyle`.Toastify__toast-container { z-index: 9999; -webkit-transform: translateZ(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) { .Toastifytoast-container { width: 100vw; padding: 0; left: 0; margin: 0 } .Toastifytoast-container--top-center, .Toastifytoast-container--top-left, .Toastifytoast-container--top-right { top: 0; transform: translateX(0) } .Toastifytoast-container--bottom-center, .Toastifytoast-container--bottom-left, .Toastifytoast-container--bottom-right { bottom: 0; transform: translateX(0) } .Toastifytoast-container--rtl { right: 0; left: auto } }

.Toastify__toast { position: relative; min-height: 64px; box-sizing: border-box; margin-bottom: 1rem; padding: 8px; border-radius: 1px; box-shadow: 0 1px 10px 0 rgba(0, 0, 0, .1), 0 2px 15px 0 rgba(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 }

@media only screen and (max-width:480px) { .Toastify__toast { margin-bottom: 0 } }

.Toastify__close-button { color: #fff; background: transparent; outline: none; border: none; padding: 0; cursor: pointer; opacity: .7; transition: .3s ease; -ms-flex-item-align: start; align-self: flex-start }

.Toastify__close-button--default { color: #000; opacity: .3 }

.Toastify__close-button>svg { fill: currentColor; height: 16px; width: 14px }

.Toastifyclose-button:focus, .Toastifyclose-button:hover { opacity: 1 }

@keyframes Toastify__trackProgress { 0% { transform: scaleX(1) } to { transform: scaleX(0) } }

.Toastify__progress-bar { position: absolute; bottom: 0; left: 0; width: 100%; height: 5px; z-index: 9999; opacity: .7; background-color: hsla(0, 0%, 100%, .7); transform-origin: left }

.Toastifyprogress-bar--animated { animation: ToastifytrackProgress linear 1 forwards }

.Toastify__progress-bar--controlled { transition: transform .2s }

.Toastify__progress-bar--rtl { right: 0; left: auto; transform-origin: right }

.Toastify__progress-bar--default { background: linear-gradient(90deg, #4cd964, #5ac8fa, #007aff, #34aadc, #5856d6, #ff2d55) }

.Toastify__progress-bar--dark { background: #bb86fc }

@keyframes Toastify__bounceInRight { 0%, 60%, 75%, 90%, to { animation-timing-function: cubic-bezier(.215, .61, .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__bounceOutRight { 20% { opacity: 1; transform: translate3d(-20px, 0, 0) } to { opacity: 0; transform: translate3d(2000px, 0, 0) } }

@keyframes Toastify__bounceInLeft { 0%, 60%, 75%, 90%, to { animation-timing-function: cubic-bezier(.215, .61, .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 { 0%, 60%, 75%, 90%, to { animation-timing-function: cubic-bezier(.215, .61, .355, 1) } 0% { 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: translateZ(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 { 0%, 60%, 75%, 90%, to { animation-timing-function: cubic-bezier(.215, .61, .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) } }

.Toastifybounce-enter--bottom-left, .Toastifybounce-enter--top-left { animation-name: Toastify__bounceInLeft }

.Toastifybounce-enter--bottom-right, .Toastifybounce-enter--top-right { animation-name: Toastify__bounceInRight }

.Toastifybounce-enter--top-center { animation-name: ToastifybounceInDown }

.Toastifybounce-enter--bottom-center { animation-name: ToastifybounceInUp }

.Toastifybounce-exit--bottom-left, .Toastifybounce-exit--top-left { animation-name: Toastify__bounceOutLeft }

.Toastifybounce-exit--bottom-right, .Toastifybounce-exit--top-right { animation-name: Toastify__bounceOutRight }

.Toastifybounce-exit--top-center { animation-name: ToastifybounceOutUp }

.Toastifybounce-exit--bottom-center { animation-name: ToastifybounceOutDown }

@keyframes Toastify__zoomIn { 0% { opacity: 0; transform: scale3d(.3, .3, .3) } 50% { opacity: 1 } }

@keyframes Toastify__zoomOut { 0% { opacity: 1 } 50% { opacity: 0; transform: scale3d(.3, .3, .3) } to { opacity: 0 } }

.Toastifyzoom-enter { animation-name: ToastifyzoomIn }

.Toastifyzoom-exit { animation-name: ToastifyzoomOut }

@keyframes Toastify__flipIn { 0% { transform: perspective(400px) rotateX(90deg); animation-timing-function: ease-in; opacity: 0 } 40% { transform: perspective(400px) rotateX(-20deg); animation-timing-function: ease-in } 60% { transform: perspective(400px) rotateX(10deg); opacity: 1 } 80% { transform: perspective(400px) rotateX(-5deg) } to { transform: perspective(400px) } }

@keyframes Toastify__flipOut { 0% { transform: perspective(400px) } 30% { transform: perspective(400px) rotateX(-20deg); opacity: 1 } to { transform: perspective(400px) rotateX(90deg); opacity: 0 } }

.Toastifyflip-enter { animation-name: ToastifyflipIn }

.Toastifyflip-exit { animation-name: ToastifyflipOut }

@keyframes Toastify__slideInRight { 0% { transform: translate3d(110%, 0, 0); visibility: visible } to { transform: translateZ(0) } }

@keyframes Toastify__slideInLeft { 0% { transform: translate3d(-110%, 0, 0); visibility: visible } to { transform: translateZ(0) } }

@keyframes Toastify__slideInUp { 0% { transform: translate3d(0, 110%, 0); visibility: visible } to { transform: translateZ(0) } }

@keyframes Toastify__slideInDown { 0% { transform: translate3d(0, -110%, 0); visibility: visible } to { transform: translateZ(0) } }

@keyframes Toastify__slideOutRight { 0% { transform: translateZ(0) } to { visibility: hidden; transform: translate3d(110%, 0, 0) } }

@keyframes Toastify__slideOutLeft { 0% { transform: translateZ(0) } to { visibility: hidden; transform: translate3d(-110%, 0, 0) } }

@keyframes Toastify__slideOutDown { 0% { transform: translateZ(0) } to { visibility: hidden; transform: translate3d(0, 500px, 0) } }

@keyframes Toastify__slideOutUp { 0% { transform: translateZ(0) } to { visibility: hidden; transform: translate3d(0, -500px, 0) } }

.Toastifyslide-enter--bottom-left, .Toastifyslide-enter--top-left { animation-name: Toastify__slideInLeft }

.Toastifyslide-enter--bottom-right, .Toastifyslide-enter--top-right { animation-name: Toastify__slideInRight }

.Toastifyslide-enter--top-center { animation-name: ToastifyslideInDown }

.Toastifyslide-enter--bottom-center { animation-name: ToastifyslideInUp }

.Toastifyslide-exit--bottom-left, .Toastifyslide-exit--top-left { animation-name: Toastify__slideOutLeft }

.Toastifyslide-exit--bottom-right, .Toastifyslide-exit--top-right { animation-name: Toastify__slideOutRight }

.Toastifyslide-exit--top-center { animation-name: ToastifyslideOutUp }

.Toastifyslide-exit--bottom-center { animation-name: ToastifyslideOutDown }`;

fkhadra commented 4 years ago

@net-bet what is your setup ? CRA, nextjs ?

Could you share a codesanbox with the issue ?

net-bet commented 4 years ago

https://codesandbox.io/s/react-hook-form-password-match-check-standard-validation-forked-24z38?file=/src/index.js

You can see in this example that toaster toasts all the way up. If you remove the comment from the import css everything looks good.

However, the css are identical. I assume it is related to the place where the toaster being positioned and styled are applied should be a root level element, probably because of the keyframes or something.

Is issue clear now?

fkhadra commented 4 years ago

Hey @net-bet,

Thanks. I managed to fix your issue. Edit React Hook Form - Password match check - Standard Validation (forked)

Instead of using styled(ToastContainer) I used createGlobalStyle from styled-components. I believe thatstyled will inject is own classNames and it kind of create conflicts

net-bet commented 4 years ago

Hi, I know it can work like this (this is how I solved it in my project) But it is still a global style :(

fkhadra commented 4 years ago

TBH the chance it's collapse with another library is quite low. But I got your point.