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

Change action button position in sonner toast #4070

Closed
2 tasks done
TJ324694 opened this issue Jun 22, 2024 · 6 comments
Closed
2 tasks done

Change action button position in sonner toast #4070

TJ324694 opened this issue Jun 22, 2024 · 6 comments

Comments

@TJ324694
Copy link

Feature description

I am currently trying to render a toast message, with a title, description and action button. And then when the action button is clicked, do a totally different thing. This is possible of course. But my issue is that my description is a bit long, like more than 40 letters, so this makes this toast message very hard to read an a bad UI.

Is there a way to change the action button in sonner toast to be at the bottom and not the right of the toast?

Affected component/components

No response

Additional Context

Additional details here...

Before submitting

  • I've made research efforts and searched the documentation
  • I've searched for existing issues and PRs
@bhaskarkhoraja
Copy link

You can try changing flex direction to column while calling toast method

<Button
  variant={"default"}
  onClick={() => {
    toast("Summer Vibes", {
      className: "flex-col", // change flex direction to column (action will be at bottom)
      description:
        "Immerse yourself ...  a lazy afternoon.", // Really really long text
      action: {
        label: "Noice",
        onClick: () => console.log("Noice"),
      },
    });
  }}
>
  Show Toast
</Button>

Output:
image

@TJ324694
Copy link
Author

You can try changing flex direction to column while calling toast method

<Button
  variant={"default"}
  onClick={() => {
    toast("Summer Vibes", {
      className: "flex-col", // change flex direction to column (action will be at bottom)
      description:
        "Immerse yourself ...  a lazy afternoon.", // Really really long text
      action: {
        label: "Noice",
        onClick: () => console.log("Noice"),
      },
    });
  }}
>
  Show Toast
</Button>

Output: image

This works as you've shown, but if I have an icon in the toast, say for toast.info, the icon goes to the center. Setting className as you've shown me to grid solves it though, so the icon goes to the beginning. My question is that how can I make the button take the whole width, like apply styles to the button specifically?

@bhaskarkhoraja
Copy link

This works as you've shown, but if I have an icon in the toast, say for toast.info, the icon goes to the center. Setting className as you've shown me to grid solves it though, so the icon goes to the beginning. My question is that how can I make the button take the whole width, like apply styles to the button specifically?

You can apply styles only to the button as well, like in Sonner Docs

<Button
  variant={"default"}
  onClick={() => {
    toast.info("Summer Vibes", {
      classNames: {
        toast: "flex-col items-start", // or use grid like you mentioned above
        actionButton: "w-full justify-center",
      },
      description:
        "Immerse yourself in the carefree spirit of summer with this vibrant and refreshing collection of content, perfect for soaking up the sun on a lazy afternoon.",
      action: {
        label: "Noice",
        onClick: () => console.log("Noice"),
      },
    });
  }}
>
  Show Toast
</Button>

Output:
image

@TJ324694
Copy link
Author

This works as you've shown, but if I have an icon in the toast, say for toast.info, the icon goes to the center. Setting className as you've shown me to grid solves it though, so the icon goes to the beginning. My question is that how can I make the button take the whole width, like apply styles to the button specifically?

You can apply styles only to the button as well, like in Sonner Docs

<Button
  variant={"default"}
  onClick={() => {
    toast.info("Summer Vibes", {
      classNames: {
        toast: "flex-col items-start", // or use grid like you mentioned above
        actionButton: "w-full justify-center",
      },
      description:
        "Immerse yourself in the carefree spirit of summer with this vibrant and refreshing collection of content, perfect for soaking up the sun on a lazy afternoon.",
      action: {
        label: "Noice",
        onClick: () => console.log("Noice"),
      },
    });
  }}
>
  Show Toast
</Button>

Output: image

Turns out that the style you suggested works, but then one can't style stuffs like the color of the button without passing unsettled: true in the toast. I tried rendering my own jsx, but then the issue of the toast no longer closing automatically shows up.

@bhaskarkhoraja
Copy link

Turns out that the style you suggested works, but then one can't style stuffs like the color of the button without passing unsettled: true in the toast. I tried rendering my own jsx, but then the issue of the toast no longer closing automatically shows up.

I think you meant to say unstyled: true, but you can change the color of button by using important in tailwind Sonner (#321). Also you must use group-[.toast]: for action or cancel button to properly target it.

<Button
  variant={"default"}
  onClick={() => {
    toast.info("Styled Button", {
      classNames: {
        toast: "flex-col items-start",
        actionButton: "w-full justify-center group-[.toast]:!bg-red-500 group-[.toast]:!text-white", // mark the class as important.
      },
      description: "Testing styled component",
      action: {
        label: "Styled",
        onClick: () => console.log("Styled"),
      },
    })
  }}
>
  Show Styled Toast
</Button>

output:
image

For custom jsx, its working perfectly fine for me and the toast closes automatically as expected (without clicking the action button).

<Button
  variant={"default"}
  onClick={() => {
    toast.custom((t) => (
      <div>
        This is a custom component
        <button onClick={() => toast.dismiss(t)}>close</button>
      </div>
    ))
  }}
>
  Show Custom Toast
</Button>

@TJ324694
Copy link
Author

@bhaskarkhoraja thank you for assistance so far, they made me go further into wanting to solve it.

Your solutions somehow wasn't just working for me, don't know why. But I took your inspiration using the !important in tailwind, so from there I just override the things I want. This was what worked.

Posting my solution incase someome comes across the same issue and doesn't want to go the mile of looking into the sonner styling that much, but just wants a quick fix:

<Button
      variant="outline"
      onClick={() =>
        toast.info("Accept birthday card", {
          description:
            "We want to send you a birthday card. Do you agree?",
          closeButton: true,
          duration: Infinity,
          action: {
            label: "Accept",
            onClick: () =>
              requestBirthdayCard({
                name: user.name,
                email: user.email,
                phoneNumber: user.phoneNumber,
              }),
          },
          classNames: {
            toast: "flex-col items-start gap-4",
            actionButton:
              "!h-8 w-full !justify-center !whitespace-nowrap !rounded-md !bg-primary !px-3 !font-medium !text-primary-foreground",
          },
        })
      }
    >
      Accept
</Button>

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

No branches or pull requests

2 participants