import Toastify from 'toastify-js'; // import { t } from './utils/l10n.js'; import './toast.css'; /** * Enum of available Toast types */ export enum ToastType { ERROR = 'toast-error', WARNING = 'toast-warning', INFO = 'toast-info', SUCCESS = 'toast-success', PERMANENT = 'toast-error', UNDO = 'toast-undo', } /** @deprecated Use ToastAriaLive.OFF */ export const TOAST_ARIA_LIVE_OFF = 'off'; /** @deprecated Use ToastAriaLive.POLITE */ export const TOAST_ARIA_LIVE_POLITE = 'polite'; /** @deprecated Use ToastAriaLive.ASSERTIVE */ export const TOAST_ARIA_LIVE_ASSERTIVE = 'assertive'; export enum ToastAriaLive { OFF = TOAST_ARIA_LIVE_OFF, POLITE = TOAST_ARIA_LIVE_POLITE, ASSERTIVE = TOAST_ARIA_LIVE_ASSERTIVE, } /** Timeout in ms of a undo toast */ export const TOAST_UNDO_TIMEOUT = 10000; /** Default timeout in ms of toasts */ export const TOAST_DEFAULT_TIMEOUT = 4000; /** Timeout value to show a toast permanently */ export const TOAST_PERMANENT_TIMEOUT = -1; /** * Type of a toast * @see https://apvarun.github.io/toastify-js/ * @notExported */ type Toast = ReturnType; export interface ToastOptions { /** * Defines the timeout in milliseconds after which the toast is closed. Set to -1 to have a persistent toast. */ timeout?: number; /** * Set to true to allow HTML content inside of the toast text * @default false */ isHTML?: boolean; /** * Set a type of {ToastType} to style the modal */ type?: ToastType; /** * Provide a function that is called after the toast is removed */ onRemove?: () => void; /** * Provide a function that is called when the toast is clicked */ onClick?: () => void; /** * Make the toast closable */ close?: boolean; /** * Specify the element to attach the toast element to (for testing) */ selector?: string; /** * Whether the messages should be announced to screen readers. * See the following docs for an explanation when to use which: * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions * * By default, errors are announced assertive and other messages "polite". */ ariaLive?: ToastAriaLive; } /** * Show a toast message * * @param data Message to be shown in the toast, any HTML is removed by default * @param options */ export function showMessage(data: string | Node, options?: ToastOptions): Toast { options = Object.assign( { timeout: TOAST_DEFAULT_TIMEOUT, isHTML: false, type: undefined, // An undefined selector defaults to the body element selector: undefined, onRemove: () => {}, onClick: undefined, close: true, }, options, ); if (typeof data === 'string' && !options.isHTML) { // fime mae sure that text is extracted const element = document.createElement('div'); element.innerHTML = data; data = element.innerText; } let classes = options.type ?? ''; if (typeof options.onClick === 'function') { classes += ' toast-with-click '; } const isNode = data instanceof Node; let ariaLive: ToastAriaLive = ToastAriaLive.POLITE; if (options.ariaLive) { ariaLive = options.ariaLive; } else if (options.type === ToastType.ERROR || options.type === ToastType.UNDO) { ariaLive = ToastAriaLive.ASSERTIVE; } const toast = Toastify({ [!isNode ? 'text' : 'node']: data, duration: options.timeout, callback: options.onRemove, onClick: options.onClick, close: options.close, gravity: 'top', selector: options.selector, position: 'right', backgroundColor: '', className: 'dialogs ' + classes, escapeMarkup: !options.isHTML, ariaLive, }); toast.showToast(); return toast; } /** * Show a toast message with error styling * * @param text Message to be shown in the toast, any HTML is removed by default * @param options */ export function showError(text: string, options?: ToastOptions): Toast { return showMessage(text, { ...options, type: ToastType.ERROR }) } export default { updatableNotification: null, getDefaultNotificationFunction: null, /** * Shows a notification that disappears after x seconds, default is * 7 seconds * * @param {string} text Message to show * @param {Array} [options] options array * @param {number} [options.timeout=7] timeout in seconds, if this is 0 it will show the message permanently * @param {boolean} [options.isHTML=false] an indicator for HTML notifications (true) or text (false) * @param {string} [options.type] notification type * @return {JQuery} the toast element */ showTemporary(text, options = { timeout: 3000 }) { options = options || {}; options.timeout = options.timeout || TOAST_DEFAULT_TIMEOUT; const toast = showMessage(text, options); toast.toastElement.toastify = toast; // return $(toast.toastElement) }, /** * Show a toast message with error styling * * @param text Message to be shown in the toast, any HTML is removed by default * @param options */ showError(text: string, options?: ToastOptions): Toast { return showMessage(text, { ...options, type: ToastType.ERROR }); }, /** * Show a toast message with warning styling * * @param text Message to be shown in the toast, any HTML is removed by default * @param options */ showWarning(text: string, options?: ToastOptions): Toast { return showMessage(text, { ...options, type: ToastType.WARNING }); }, /** * Show a toast message with info styling * * @param text Message to be shown in the toast, any HTML is removed by default * @param options */ showInfo(text: string, options?: ToastOptions): Toast { return showMessage(text, { ...options, type: ToastType.INFO }); }, /** * Show a toast message with success styling * * @param text Message to be shown in the toast, any HTML is removed by default * @param options */ showSuccess(text: string, options?: ToastOptions): Toast { return showMessage(text, { ...options, type: ToastType.SUCCESS }); }, };