Subversion Repositories oidplus

Rev

View as "text/javascript" | Blame | Last modification | View Log | RSS feed

  1. import Bs5Utils from "../Bs5Utils";
  2.  
  3. export default class Toast {
  4.     /**
  5.      * A counter for the Toasts
  6.      * @type {number}
  7.      */
  8.     #count = 0;
  9.  
  10.     /**
  11.      * Display a toast for alerts
  12.      * @param type - the theme of the snack
  13.      * @param icon - Set an icon in the top-left corner, you can pass HTML directly
  14.      * @param title - the title of the of the toast
  15.      * @param subtitle - the subtitle of the toast
  16.      * @param content - the content of the toast
  17.      * @param buttons - the action buttons of the toast
  18.      * @param delay - in ms, if specified the snack will autohide after the specified amount
  19.      * @param dismissible - set whether the dismiss button should show
  20.      */
  21.     show({
  22.              type,
  23.              icon = '',
  24.              title,
  25.              subtitle = '',
  26.              content = '',
  27.              buttons = [],
  28.              delay = 0,
  29.              dismissible = true
  30.          }) {
  31.         this.#count++;
  32.  
  33.         const style = Bs5Utils.defaults.styles[type],
  34.             btnCloseStyles = style.btnClose.join(' '),
  35.             borderStyles = style.border,
  36.             toast = document.createElement('div');
  37.  
  38.         toast.setAttribute('id', `toast-${this.#count}`);
  39.         toast.setAttribute('role', 'alert');
  40.         toast.setAttribute('aria-live', 'assertive');
  41.         toast.setAttribute('aria-atomic', 'true');
  42.  
  43.         toast.classList.add('toast', 'align-items-center');
  44.         borderStyles.forEach(value => {
  45.             toast.classList.add(value);
  46.         });
  47.  
  48.         let buttonsHtml = ``,
  49.             buttonIds = [];
  50.  
  51.         if (Array.isArray(buttons) && buttons.length) {
  52.             buttonsHtml += `<div class="d-flex justify-content-center mt-2 pt-2 border-top ${borderStyles.join(' ')}">`;
  53.  
  54.             buttons.forEach((button, key) => {
  55.                 const type = button.type || 'button';
  56.  
  57.                 switch (type) {
  58.                     case 'dismiss':
  59.                         buttonsHtml += `<button type="button" class="${button.class}" data-bs-dismiss="toast">${button.text}</button>&nbsp;`;
  60.                         break;
  61.  
  62.                     default:
  63.                         let id = `toast-${this.#count}-button-${key}`;
  64.  
  65.                         buttonsHtml += `<button type="button" id="${id}" class="${button.class}">${button.text}</button>&nbsp;`;
  66.  
  67.                         if (button.hasOwnProperty('handler') && typeof button.handler === 'function') {
  68.                             buttonIds.push({
  69.                                 id,
  70.                                 handler: button.handler
  71.                             });
  72.                         }
  73.                 }
  74.             });
  75.  
  76.             buttonsHtml += `</div>`;
  77.         }
  78.  
  79.         toast.innerHTML = `<div class="toast-header ${style.main.join(' ')}">
  80.                             ${icon}
  81.                             <strong class="me-auto">${title}</strong>
  82.                             <small>${subtitle}</small>
  83.                             ${dismissible ? `<button type="button" class="btn-close ${btnCloseStyles}" data-bs-dismiss="toast" aria-label="Close"></button>` : ''}
  84.                         </div>
  85.                         <div class="toast-body">
  86.                             ${content}
  87.                             ${buttonsHtml}
  88.                         </div>`;
  89.  
  90.         if (!Bs5Utils.defaults.toasts.stacking) {
  91.             document.querySelectorAll(`#${Bs5Utils.defaults.toasts.container} .toast`).forEach((toast) => {
  92.                 toast.remove();
  93.             });
  94.         }
  95.  
  96.         document.querySelector(`#${Bs5Utils.defaults.toasts.container}`).appendChild(toast);
  97.  
  98.         toast.addEventListener('hidden.bs.toast', function (e) {
  99.             e.target.remove();
  100.         });
  101.  
  102.         buttonIds.forEach(value => {
  103.             document.getElementById(value.id).addEventListener('click', value.handler)
  104.         });
  105.  
  106.         const opts = {
  107.             autohide: (delay > 0 && typeof delay === 'number'),
  108.         };
  109.  
  110.         if (delay > 0 && typeof delay === 'number') {
  111.             opts['delay'] = delay;
  112.         }
  113.  
  114.         const bsToast = new bootstrap.Toast(toast, opts);
  115.  
  116.         bsToast.show();
  117.  
  118.         return bsToast;
  119.     }
  120. }