Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default classNames are not working for other variants #242

Closed
imopbuilder opened this issue Nov 30, 2023 · 15 comments
Closed

Default classNames are not working for other variants #242

imopbuilder opened this issue Nov 30, 2023 · 15 comments

Comments

@imopbuilder
Copy link
Contributor

'use client';

import { useTheme } from 'next-themes';
import { Toaster } from 'sonner';

export function ToastProvider() {
	const { theme } = useTheme();

	return (
		<Toaster
			toastOptions={{
				classNames: {
					toast: '!border-border',
				},
			}}
			theme={theme as 'light' | 'dark' | 'system'}
			richColors
		/>
	);
}

When the classNames for toast are changed then the error default styles are also changed even when the error styles are not being touched

@emilkowalski
Copy link
Owner

That's expected, if you want differrent styling for different toast types you can use it like this:

<Toaster
  toastOptions={{
    unstyled: true,
    classNames: {
      error: 'bg-red-400',
      success: 'text-green-400',
      warning: 'text-yellow-400',
      info: 'bg-blue-400',
    },
  }}
/>

@imopbuilder
Copy link
Contributor Author

No the styling is applied for all variants when applied to toast variant ignoring the default styling for other variants

@emilkowalski
Copy link
Owner

Again, that's expected. Everything you apply to toast is also applied to all toast types.

@imopbuilder
Copy link
Contributor Author

I want to change the default style of the toast when we call the toast like this

toast('Event has been created')

because I would like to apply the shadcn themes for the toast when the default toast is being called and it should not change the styling of the other variants

@imopbuilder
Copy link
Contributor Author

@emilkowalski can I make a PR for the default property which takes the styling in the classNames so that it will not effect the other variants

@emilkowalski
Copy link
Owner

@imopbuilder Of course, go for it!

@imopbuilder
Copy link
Contributor Author

@imopbuilder Of course, go for it!

sure I will start working on it

@imopbuilder
Copy link
Contributor Author

imopbuilder commented Dec 3, 2023

@emilkowalski I have made a PR #245 by add the default property to the types and also to the state

@justinnais
Copy link

This is still an issue as the type: 'default' was removed in this commit.

I'm trying to apply styling to each variant, while also styling the default to allow usage of toast().

However, applying classes to classNames.toast overwrites the variant styling. The default classname is useless as the toastType is undefined, so it doesn't apply any styles.

export const Toaster = (props: ToasterProps) => (
  <Sonner.Toaster
    toastOptions={{
      classNames: {
        error: "bg-red",
        success: "bg-green",
        warning: "bg-yellow",
        info: "bg-blue",
        // default classes are never applied
        default: "bg-white",
        // can't use bg-white here because it overwrites variant classes
        // toast: "bg-white",
      },
      unstyled: true,
    }}
    {...props}
  />
)

Is there a reason default type was removed?

FYI I'm working around this by checking for toasts that don't have the data-type attribute on them:

[data-sonner-toaster] li:not([data-type]) {
    @apply bg-white;
  }

@imopbuilder
Copy link
Contributor Author

imopbuilder commented Jan 5, 2024

@justinnais yes the property has been removed in the commit but the types are not updated hence the default type is undefined but you can refer to this link where shadcn-ui used sonner toast to changed the styles for the toast() without affecting other variants

Shadcn-ui sonner toast (take a look at the manual installation)

Here is the implementation

// Toaster.tsx

"use client"

import { useTheme } from "next-themes"
import { Toaster as Sonner } from "sonner"

type ToasterProps = React.ComponentProps<typeof Sonner>

const Toaster = ({ ...props }: ToasterProps) => {
  const { theme = "system" } = useTheme()

  return (
    <Sonner
      theme={theme as ToasterProps["theme"]}
      className="toaster group"
      toastOptions={{
        classNames: {
          toast:
            "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
          description: "group-[.toast]:text-muted-foreground",
          actionButton:
            "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
          cancelButton:
            "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
        },
      }}
      {...props}
    />
  )
}

export { Toaster }

Make sure to add richColors in the toastOptions

@justinnais
Copy link

@imopbuilder richColors overrides the colors that I am passing into the class names, which isn't what I'm after unfortunately. I had a play with the tailwind group classes but it doesn't solve the issue of the toast class overriding all of the variant classes.

Should the default type be removed entirely, or should the prop be added back to the default toast?

@wadeamaral
Copy link

However, applying classes to classNames.toast overwrites the variant styling.

export const Toaster = (props: ToasterProps) => (
  <Sonner.Toaster
    toastOptions={{
      classNames: {
        error: "bg-red",
        success: "bg-green",
        warning: "bg-yellow",
        info: "bg-blue",
        // This variant should be applied first in the chain, not last, so that any similarly defined style above takes precedence
        // Currently none of the other variants work as they will all appear white
        // toast: "bg-white",
      },
      unstyled: true,
    }}
    {...props}
  />
)

Do we have an update on this? This is pretty frustrating to work around. Intuitively any of the styling for the "variant" toasts (error, success, warning, info) should be applied after the "default" toast (toast).

@emilkowalski
Copy link
Owner

This is fixed in #324. You can now style with the default key, those styles will be overidden by any type specific ones.

@wadeamaral
Copy link

This is fixed in #324. You can now style with the default key, those styles will be overidden by any type specific ones.

Just a heads up that I pulled the latest version 1.4.1 and it seems the "error" variant is still using the background color as styled in either "toast" or "default". The "success" variant is working correctly however.

I also wanted to say thank you for a wonderful toast component.

@junwen-k
Copy link

This is fixed in #324. You can now style with the default key, those styles will be overidden by any type specific ones.

Just a heads up that I pulled the latest version 1.4.1 and it seems the "error" variant is still using the background color as styled in either "toast" or "default". The "success" variant is working correctly however.

I also wanted to say thank you for a wonderful toast component.

I had the same issue and I realised that the issue was due to my class name for my error variant (bg-error-background) is before my default variant (bg-foreground) *Notice alphabet e comes before alphabet f.

The fix is to provide custom cn function via cn prop that includes tw-merge so that the ordering of the class name will be correct. If you are coming from shadcn, you can just do

'use client';

import { cn } from '@/lib/utils';

// ...

<Sonner
  // ...
  cn={cn}
  // ...
/>

Hopefully that helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants