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

Enhanced Configuration for toast.promise States #464

Open
bakikucukcakiroglu opened this issue Jul 2, 2024 · 6 comments
Open

Enhanced Configuration for toast.promise States #464

bakikucukcakiroglu opened this issue Jul 2, 2024 · 6 comments

Comments

@bakikucukcakiroglu
Copy link

bakikucukcakiroglu commented Jul 2, 2024

Feature Request: Enhanced Configuration for toast.promise States

Problem Statement:
Currently, toast.promise supports basic customization of messages for different states (loading, success, error), but lacks support for detailed configurations like different actions and descriptions for each state. If a user tries to add a custom component to implement description and buttons, they lose the consistent styling provided by the library(also code becomes cumbersome).

Using data and error parameters to show a toast description, supplying an action based on the result of the promise would be really elegant. You can make user go to the output's page on success while open logs on error.

Note: Please let me know if there is an easy way of doing that but I'm missing.

Example Usage:

toast.promise(
    new Promise((resolve, reject) => {
        setTimeout(() => {
            if (Math.random() > 0.2) {
                resolve("Transcription successful");
            } else {
                reject("Transcription failed");
            }
        }, 1000);
    }), {
        loading: {
           "Loading", {
               description: "Please wait for a few seconds..."
            }
        },
        success: {
            "Transcription successful", {
            description: "Your transcription has been completed successfully.",
               action: {
                   label: "View transcription",
                   onClick: () => {
                       console.log("View transcription");
                   }
               }
           }
        },
        error: {
            "Transcription failed", {
               description: "Unable to complete your transcription at this time."
            }
        }
    }
);
@vinhloc30796
Copy link

vinhloc30796 commented Jul 7, 2024

It's looking like this would be the place to implement the thing

sonner/src/state.ts

Lines 107 to 165 in 2b99cd8

promise = <ToastData>(promise: PromiseT<ToastData>, data?: PromiseData<ToastData>) => {
if (!data) {
// Nothing to show
return;
}
let id: string | number | undefined = undefined;
if (data.loading !== undefined) {
id = this.create({
...data,
promise,
type: 'loading',
message: data.loading,
description: typeof data.description !== 'function' ? data.description : undefined,
});
}
const p = promise instanceof Promise ? promise : promise();
let shouldDismiss = id !== undefined;
p.then(async (response) => {
if (isHttpResponse(response) && !response.ok) {
shouldDismiss = false;
const message =
typeof data.error === 'function' ? await data.error(`HTTP error! status: ${response.status}`) : data.error;
const description =
typeof data.description === 'function'
? await data.description(`HTTP error! status: ${response.status}`)
: data.description;
this.create({ id, type: 'error', message, description });
} else if (data.success !== undefined) {
shouldDismiss = false;
const message = typeof data.success === 'function' ? await data.success(response) : data.success;
const description =
typeof data.description === 'function' ? await data.description(response) : data.description;
this.create({ id, type: 'success', message, description });
}
})
.catch(async (error) => {
if (data.error !== undefined) {
shouldDismiss = false;
const message = typeof data.error === 'function' ? await data.error(error) : data.error;
const description = typeof data.description === 'function' ? await data.description(error) : data.description;
this.create({ id, type: 'error', message, description });
}
})
.finally(() => {
if (shouldDismiss) {
// Toast is still in load state (and will be indefinitely — dismiss it)
this.dismiss(id);
id = undefined;
}
data.finally?.();
});
return id;
};

@Jkense
Copy link

Jkense commented Jul 8, 2024

I've been struggling with the same thing here. I would love to have the same action buttons in my promise messages, but it lacks a lot of flexibility.

@Jkense
Copy link

Jkense commented Jul 8, 2024

Just found this:

#413

@bakikucukcakiroglu
Copy link
Author

bakikucukcakiroglu commented Jul 13, 2024

Just found this:

#413

Actually I was aware of that.
'If a user tries to add a custom component to implement description and buttons, they lose the consistent styling provided by the library(also code becomes cumbersome).'

I think implementing description and buttons for promised toasts is a better approach since it also make the developers use the same structure for showing a toast regardless of it is promised or not.

@Jkense
Copy link

Jkense commented Jul 16, 2024

Just found this:

#413

Actually I was aware of that.
'If a user tries to add a custom component to implement description and buttons, they lose the consistent styling provided by the library(also code becomes cumbersome).'

I think implementing description and buttons for promised toasts is a better approach since it also make the developers use the same structure for showing a toast regardless of it is promised or not.

Agreed, the whole point should be to reduce code and take it out of our components

@raunaq-iprally
Copy link

I was just trying to figure this out myself.
I was wondering if there is way to add a description and action to loading state?

Just showing the label: 'Loading...' is not sufficient at times.
For example: for my usecase, loading state can take minutes, in that case I would want the user to be able to say 'notify me when this completes' or something

Is there a better way to achieve this?
Apologies, I am not advance in coding

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

4 participants