notif.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. app.views.Notif = class Notif extends app.View {
  2. static className = "_notif";
  3. static activeClass = "_in";
  4. static attributes = { role: "alert" };
  5. static defaultOptions = { autoHide: 15000 };
  6. static events = { click: "onClick" };
  7. constructor(type, options) {
  8. super();
  9. this.type = type;
  10. this.options = { ...this.constructor.defaultOptions, ...(options || {}) };
  11. this.init0(); // needs this.options
  12. this.refreshElements();
  13. }
  14. init0() {
  15. this.show();
  16. }
  17. show() {
  18. if (this.timeout) {
  19. clearTimeout(this.timeout);
  20. this.timeout = this.delay(this.hide, this.options.autoHide);
  21. } else {
  22. this.render();
  23. this.position();
  24. this.activate();
  25. this.appendTo(document.body);
  26. this.el.offsetWidth; // force reflow
  27. this.addClass(this.constructor.activeClass);
  28. if (this.options.autoHide) {
  29. this.timeout = this.delay(this.hide, this.options.autoHide);
  30. }
  31. }
  32. }
  33. hide() {
  34. clearTimeout(this.timeout);
  35. this.timeout = null;
  36. this.detach();
  37. }
  38. render() {
  39. this.html(this.tmpl(`notif${this.type}`));
  40. }
  41. position() {
  42. const notifications = $$(`.${Notif.className}`);
  43. if (notifications.length) {
  44. const lastNotif = notifications[notifications.length - 1];
  45. this.el.style.top =
  46. lastNotif.offsetTop + lastNotif.offsetHeight + 16 + "px";
  47. }
  48. }
  49. onClick(event) {
  50. if (event.which !== 1) {
  51. return;
  52. }
  53. const target = $.eventTarget(event);
  54. if (target.hasAttribute("data-behavior")) {
  55. return;
  56. }
  57. if (target.tagName !== "A" || target.classList.contains("_notif-close")) {
  58. $.stopEvent(event);
  59. this.hide();
  60. }
  61. }
  62. };