flash.js 3.13 KB
Newer Older
Phil Hughes's avatar
Phil Hughes committed
1
import _ from 'underscore';
Fatih Acet's avatar
Fatih Acet committed
2

Phil Hughes's avatar
Phil Hughes committed
3 4 5 6 7 8 9
const hideFlash = (flashEl, fadeTransition = true) => {
  if (fadeTransition) {
    Object.assign(flashEl.style, {
      transition: 'opacity .3s',
      opacity: '0',
    });
  }
Fatih Acet's avatar
Fatih Acet committed
10

11 12 13 14 15 16 17 18 19 20 21 22 23
  flashEl.addEventListener(
    'transitionend',
    () => {
      flashEl.remove();
      window.dispatchEvent(new Event('resize'));
      if (document.body.classList.contains('flash-shown'))
        document.body.classList.remove('flash-shown');
    },
    {
      once: true,
      passive: true,
    },
  );
Phil Hughes's avatar
Phil Hughes committed
24 25

  if (!fadeTransition) flashEl.dispatchEvent(new Event('transitionend'));
Phil Hughes's avatar
Phil Hughes committed
26
};
27

Phil Hughes's avatar
Phil Hughes committed
28 29 30 31
const createAction = config => `
  <a
    href="${config.href || '#'}"
    class="flash-action"
Phil Hughes's avatar
Phil Hughes committed
32
    ${config.href ? '' : 'role="button"'}
Phil Hughes's avatar
Phil Hughes committed
33 34 35 36
  >
    ${_.escape(config.title)}
  </a>
`;
37

38
const createFlashEl = (message, type, isFixedLayout = false) => `
Phil Hughes's avatar
Phil Hughes committed
39 40 41 42
  <div
    class="flash-${type}"
  >
    <div
43
      class="flash-text ${isFixedLayout ? 'container-fluid container-limited limit-container-width' : ''}"
Phil Hughes's avatar
Phil Hughes committed
44 45 46 47 48
    >
      ${_.escape(message)}
    </div>
  </div>
`;
49

50
const removeFlashClickListener = (flashEl, fadeTransition) => {
51
  flashEl.addEventListener('click', () => hideFlash(flashEl, fadeTransition));
52 53
};

Phil Hughes's avatar
Phil Hughes committed
54 55 56 57 58
/*
 *  Flash banner supports different types of Flash configurations
 *  along with ability to provide actionConfig which can be used to show
 *  additional action or link on banner next to message
 *
Phil Hughes's avatar
Phil Hughes committed
59 60 61 62 63 64 65 66
 *  @param {String} message           Flash message text
 *  @param {String} type              Type of Flash, it can be `notice` or `alert` (default)
 *  @param {Object} parent            Reference to parent element under which Flash needs to appear
 *  @param {Object} actonConfig       Map of config to show action on banner
 *    @param {String} href            URL to which action config should point to (default: '#')
 *    @param {String} title           Title of action
 *    @param {Function} clickHandler  Method to call when action is clicked on
 *  @param {Boolean} fadeTransition   Boolean to determine whether to fade the alert out
Phil Hughes's avatar
Phil Hughes committed
67 68 69 70 71 72 73
 */
const createFlash = function createFlash(
  message,
  type = 'alert',
  parent = document,
  actionConfig = null,
  fadeTransition = true,
Tim Zallmann's avatar
Tim Zallmann committed
74
  addBodyClass = false,
Phil Hughes's avatar
Phil Hughes committed
75
) {
Phil Hughes's avatar
Phil Hughes committed
76
  const flashContainer = parent.querySelector('.flash-container');
77
  const navigation = parent.querySelector('.content');
Phil Hughes's avatar
Phil Hughes committed
78 79 80

  if (!flashContainer) return null;

81
  const isFixedLayout = navigation ? navigation.parentNode.classList.contains('container-limited') : true;
Phil Hughes's avatar
Phil Hughes committed
82

83
  flashContainer.innerHTML = createFlashEl(message, type, isFixedLayout);
84

Phil Hughes's avatar
Phil Hughes committed
85
  const flashEl = flashContainer.querySelector(`.flash-${type}`);
86
  removeFlashClickListener(flashEl, fadeTransition);
87

Phil Hughes's avatar
Phil Hughes committed
88 89 90 91
  if (actionConfig) {
    flashEl.innerHTML += createAction(actionConfig);

    if (actionConfig.clickHandler) {
92 93 94
      flashEl
        .querySelector('.flash-action')
        .addEventListener('click', e => actionConfig.clickHandler(e));
Fatih Acet's avatar
Fatih Acet committed
95
    }
96
  }
Fatih Acet's avatar
Fatih Acet committed
97

Phil Hughes's avatar
Phil Hughes committed
98 99
  flashContainer.style.display = 'block';

Tim Zallmann's avatar
Tim Zallmann committed
100 101
  if (addBodyClass) document.body.classList.add('flash-shown');

Phil Hughes's avatar
Phil Hughes committed
102 103 104
  return flashContainer;
};

105
export { createFlash as default, createFlashEl, createAction, hideFlash, removeFlashClickListener };
Phil Hughes's avatar
Phil Hughes committed
106
window.Flash = createFlash;