Files
NapCatQQ/.pnpm-store/v3/files/ec/28f72b916bd5a9144f8477637e7ad854cfdf6353c665a4032b6d26035e5e2f9c66d5f993eb981f5150b2f885814b79b4169d68bab2a040b56bed7cb9e0846c
T
TanTan e311ca3275
Build NapCat Artifacts / Type Check & Test (push) Waiting to run
docs: 仓库链接指向本镜像仓库
2026-11-13 09:25:58 +08:00

160 lines
3.4 KiB
Plaintext

import {
Renderable,
Toast,
ToastOptions,
ToastType,
DefaultToastOptions,
ValueOrFunction,
resolveValue,
} from './types';
import { genId } from './utils';
import {
createDispatch,
Action,
ActionType,
dispatchAll,
getToasterIdFromToastId,
} from './store';
type Message = ValueOrFunction<Renderable, Toast>;
type ToastHandler = (message: Message, options?: ToastOptions) => string;
const createToast = (
message: Message,
type: ToastType = 'blank',
opts?: ToastOptions
): Toast => ({
createdAt: Date.now(),
visible: true,
dismissed: false,
type,
ariaProps: {
role: 'status',
'aria-live': 'polite',
},
message,
pauseDuration: 0,
...opts,
id: opts?.id || genId(),
});
const createHandler =
(type?: ToastType): ToastHandler =>
(message, options) => {
const toast = createToast(message, type, options);
const dispatch = createDispatch(
toast.toasterId || getToasterIdFromToastId(toast.id)
);
dispatch({ type: ActionType.UPSERT_TOAST, toast });
return toast.id;
};
const toast = (message: Message, opts?: ToastOptions) =>
createHandler('blank')(message, opts);
toast.error = createHandler('error');
toast.success = createHandler('success');
toast.loading = createHandler('loading');
toast.custom = createHandler('custom');
/**
* Dismisses the toast with the given id. If no id is given, dismisses all toasts.
* The toast will transition out and then be removed from the DOM.
* Applies to all toasters, except when a `toasterId` is given.
*/
toast.dismiss = (toastId?: string, toasterId?: string) => {
const action: Action = {
type: ActionType.DISMISS_TOAST,
toastId,
};
if (toasterId) {
createDispatch(toasterId)(action);
} else {
dispatchAll(action);
}
};
/**
* Dismisses all toasts.
*/
toast.dismissAll = (toasterId?: string) => toast.dismiss(undefined, toasterId);
/**
* Removes the toast with the given id.
* The toast will be removed from the DOM without any transition.
*/
toast.remove = (toastId?: string, toasterId?: string) => {
const action: Action = {
type: ActionType.REMOVE_TOAST,
toastId,
};
if (toasterId) {
createDispatch(toasterId)(action);
} else {
dispatchAll(action);
}
};
/**
* Removes all toasts.
*/
toast.removeAll = (toasterId?: string) => toast.remove(undefined, toasterId);
/**
* Create a loading toast that will automatically updates with the promise.
*/
toast.promise = <T>(
promise: Promise<T> | (() => Promise<T>),
msgs: {
loading: Renderable;
success?: ValueOrFunction<Renderable, T>;
error?: ValueOrFunction<Renderable, any>;
},
opts?: DefaultToastOptions
) => {
const id = toast.loading(msgs.loading, { ...opts, ...opts?.loading });
if (typeof promise === 'function') {
promise = promise();
}
promise
.then((p) => {
const successMessage = msgs.success
? resolveValue(msgs.success, p)
: undefined;
if (successMessage) {
toast.success(successMessage, {
id,
...opts,
...opts?.success,
});
} else {
toast.dismiss(id);
}
return p;
})
.catch((e) => {
const errorMessage = msgs.error ? resolveValue(msgs.error, e) : undefined;
if (errorMessage) {
toast.error(errorMessage, {
id,
...opts,
...opts?.error,
});
} else {
toast.dismiss(id);
}
});
return promise;
};
export { toast };