Closed FleetAdmiralJakob closed 10 months ago
Hi @FleetAdmiralJakob,
Thanks for your suggestion. You can actually already use variants. Here's an example:
toast.success('Event has been created')
toast.error('Event has not been created')
// warning, info etc
Check here for more details : https://sonner.emilkowal.ski/
And another thing, you can also style the sooner with css as well as tailwind css also, like this with Toaster component
<Toaster
toastOptions={{
unstyled: true,
classNames: {
error: 'bg-red-400',
success: 'text-green-400',
warning: 'text-yellow-400',
info: 'bg-blue-400',
},
}}
/>
or also with toast function:
toast('Hello World', {
unstyled: true,
classNames: {
toast: 'bg-blue-400',
title: 'text-red-400 text-2xl',
description: 'text-red-400',
actionButton: 'bg-zinc-400',
cancelButton: 'bg-orange-400',
closeButton: 'bg-lime-400',
},
});
as mentioned here in the documentation
For more advanced usages, you can directly check out the documentation: https://sonner.emilkowal.ski/getting-started
Feel free to ask any questions if you are not satisfied with the answer.
@jrTilak would really appreciate some pointers in terms of what I'm missing here -
import { toast } from 'sonner';
//...
return(
<Button
onClick={() => {
toast.error('my dummy error message', {
unstyled: true,
duration: 9000000,
classNames: {
error: 'bg-red-400',
info: 'bg-blue-400',
success: 'bg-green-400',
warning: 'bg-orange-400',
toast: 'bg-blue-400',
title: 'text-red-400 text-2xl',
description: 'text-red-400',
actionButton: 'bg-zinc-400',
cancelButton: 'bg-orange-400',
closeButton: 'bg-lime-400',
},
});
}}
>
<div className="flex items-center justify-center">
<span>Show Error Toast</span>
</div>
</Button>
)
I understand that a lot more styles will have to go there if I'm opting for unstyled
. However, it doesn't look like any of those styles are taking into action, as this is all I'm getting -
What's interesting though is that looks like only the text-2xl
portion from title: 'text-red-400 text-2xl',
is taking into action, but nothing else. Any thoughts on what I'm missing here?
And in case it helps, my components/ui/sonner.tsx
is exactly as it is after it gets installed and following is how I've added Toaster
at the global level -
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<Toaster />
<AuthProvider>
<RouterProvider router={router} />
</AuthProvider>
<ReactQueryDevtools />
</QueryClientProvider>
</React.StrictMode>,
);
I also noticed that the styles are not being applied using the method you are using.
After doing some trials here are my findings:
bg-red-400
, the default style background-color: hsl(var(--background));
overwrites the style.text-2xl
is working , it is because there is no default font size.
It maybe bug or something , I guess
The unstyled=true
is not working properly maybe.https://github.com/shadcn-ui/ui/assets/106688422/988409fb-64a2-4e25-a597-edeaa30a26af
For now you can provide the same styles to <Toaster/>
instead of toast()
like this and it works as expected.
<Toaster toastOptions={{
unstyled: true,
duration: 9000000,
classNames: {
error: 'bg-red-400',
info: 'bg-blue-400',
success: 'bg-green-400',
warning: 'bg-orange-400',
toast: 'bg-blue-400',
title: 'text-red-400 text-2xl',
description: 'text-red-400',
actionButton: 'bg-zinc-400',
cancelButton: 'bg-orange-400',
closeButton: 'bg-lime-400',
},
}}/>
you can directly import the <Toaster/>
from sooner
import { Toaster } from 'sonner';
I think it is some bug from shadcn
as sooner
is working fine when we import form sooner
and does not work when import form shadcn
.
I guess you should open a issue, if you want.
If you are not satisfied with the answer, you can ask more❤️
thanks for looking into it @jrTilak , appreciate your insight!
in my case, using toaster
from sonner
is a better and more scalable option than the component (<Toaster/>
) flavor of it. I am importing sonner
directly from sonner
in my component (as well as importing <Toaster/>
directly from sonner in my main.tsx
. I just happened to install it through shadcn
. So I'm not quite sure if it's necessarily a bug from shadcn
.
Having said that, I think you're right regarding there being some sort of style overriding going on. What I'm not sure about though is the source - this style overriding seems to be originating from the library itself (?), i.e., in the video, where you're inspecting the styles for the background color, it's coming from the .group.toaster
class(es), which are coming from the library, right?
As a workaround, what I found working for me is the following -
toast.custom(
(t) => {
return (
<div className="flex justify-between">
<div className="flex items-center">
<Alert />
<div className="ml-2">This is a dummy error message</div>
</div>
<Button
className="text-white"
variant="link"
onClick={() => toast.dismiss(t)}
>
<Cancel />
</Button>
</div>
);
},
{
unstyled: true,
duration: 9000000,
description: 'some generic text',
classNames: {
toast:
'bg-green-100 rounded-lg py-2 px-4 shadow-lg text-white w-96',
},
},
);
Basically putting all my styles in the toast
class and using custom jsx.
Yeah, there is some style overriding , I think it is from shadcn because if you inspect the component <Toaster/>
that you installed from shadcn, It has some styles overriding done using the tailwind variables to make the design consistent
<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}
/>
It is good things as it makes us our design consistent but it also made that drawback to overriding the styles.
As I mentioned earlier, if you pass the style props to the <Toaster/>
, it works as expected because it knows you are passing the props and use the given styles but if you pass the style props from the function it has no way to know that you are passing the styles because the Toaster
is from shadcn and toast
function is from sooner
.
That's it from me.
And glad to know you found the solution helpful.
yeah, that makes sense. Guess the best path forward in this case would be to use Toaster
from shadcn whenever applicable (and the passed styles thru classNames
will take over), and use toast
from sonner
in other cases and make use of the approach I've laid out above. Thanks!
I prefer variant like this
Just add something like this to the toastOptions
// components/ui/sonner.tsx
<Sonner
theme={theme as ToasterProps['theme']}
className="toaster group"
toastOptions={{
classNames: {
...
icon: 'group-data-[type=error]:text-red-500 group-data-[type=success]:text-green-500 group-data-[type=warning]:text-amber-500 group-data-[type=info]:text-blue-500',
},
}}
{...props}
/>
I prefer variant like this
Just add something like this to the toastOptions
// components/ui/sonner.tsx <Sonner theme={theme as ToasterProps['theme']} className="toaster group" toastOptions={{ classNames: { ... icon: 'group-data-[type=error]:text-red-500 group-data-[type=success]:text-green-500 group-data-[type=warning]:text-amber-500 group-data-[type=info]:text-blue-500', }, }} {...props} />
hi sir, Where can I get all the props or properties related to this sonner? because I need more customization
I prefer variant like this Just add something like this to the toastOptions
// components/ui/sonner.tsx <Sonner theme={theme as ToasterProps['theme']} className="toaster group" toastOptions={{ classNames: { ... icon: 'group-data-[type=error]:text-red-500 group-data-[type=success]:text-green-500 group-data-[type=warning]:text-amber-500 group-data-[type=info]:text-blue-500', }, }} {...props} />
hi sir, Where can I get all the props or properties related to this sonner? because I need more customization
You can follow the installation guide here: https://ui.shadcn.com/docs/components/sonner
After the installation, just paste the following code in components/ui/sonner.tsx
toastOptions
icon: 'group-data-[type=error]:text-red-500 group-data-[type=success]:text-green-500 group-data-[type=warning]:text-amber-500 group-data-[type=info]:text-blue-500',
// sonner.tsx
import { AlertTriangle, CheckCircle, Info, Loader, XCircle } from "lucide-react"
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",
},
}}
icons={{
success: <CheckCircle className="h-4 w-4 text-green-500" />,
info: <Info className="h-4 w-4 text-blue-500" />,
warning: <AlertTriangle className="h-4 w-4 text-amber-500" />,
error: <XCircle className="h-4 w-4 text-red-500" />,
loading: <Loader className="h-4 w-4 text-gray-500 animate-spin" />,
}}
{...props}
/>
)
}
export { Toaster }
Example how to use it :
toast.success("Success", {
description: "Profile updated successfully",
})
toast.error("Custom Title 1", {
description: "Failed to update profile",
})
return ( <Sonner theme={theme as ToasterProps['theme']} className="toaster group" toastOptions={{ classNames: { toast: 'group toast group-[.toaster]:bg-background 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', error: 'bg-red-100 text-red-800 border border-red-400', success: 'bg-green-100 text-green-800 border border-green-400', warning: 'bg-yellow-100 text-yellow-800 border border-yellow-400', info: 'bg-blue-100 text-blue-800 border border-blue-400', just get rid off the default text color and everything will be oukay ,
text-foreground group-[.toaster] get rid of this line and all will be a success
An error and an success variant of sonner would be a great addition