Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

3 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import addClass from 'dom-helpers/addClass';
  2. import removeClass from 'dom-helpers/removeClass';
  3. import css from 'dom-helpers/css';
  4. import getScrollbarSize from 'dom-helpers/scrollbarSize';
  5. import isOverflowing from './utils/isOverflowing';
  6. import { ariaHidden, hideSiblings, showSiblings } from './utils/manageAriaHidden';
  7. function findIndexOf(arr, cb) {
  8. var idx = -1;
  9. arr.some(function (d, i) {
  10. if (cb(d, i)) {
  11. idx = i;
  12. return true;
  13. }
  14. return false;
  15. });
  16. return idx;
  17. }
  18. /**
  19. * Proper state management for containers and the modals in those containers.
  20. *
  21. * @internal Used by the Modal to ensure proper styling of containers.
  22. */
  23. var ModalManager =
  24. /*#__PURE__*/
  25. function () {
  26. function ModalManager(_temp) {
  27. var _ref = _temp === void 0 ? {} : _temp,
  28. _ref$hideSiblingNodes = _ref.hideSiblingNodes,
  29. hideSiblingNodes = _ref$hideSiblingNodes === void 0 ? true : _ref$hideSiblingNodes,
  30. _ref$handleContainerO = _ref.handleContainerOverflow,
  31. handleContainerOverflow = _ref$handleContainerO === void 0 ? true : _ref$handleContainerO;
  32. this.hideSiblingNodes = hideSiblingNodes;
  33. this.handleContainerOverflow = handleContainerOverflow;
  34. this.modals = [];
  35. this.containers = [];
  36. this.data = [];
  37. this.scrollbarSize = getScrollbarSize();
  38. }
  39. var _proto = ModalManager.prototype;
  40. _proto.isContainerOverflowing = function isContainerOverflowing(modal) {
  41. var data = this.data[this.containerIndexFromModal(modal)];
  42. return data && data.overflowing;
  43. };
  44. _proto.containerIndexFromModal = function containerIndexFromModal(modal) {
  45. return findIndexOf(this.data, function (d) {
  46. return d.modals.indexOf(modal) !== -1;
  47. });
  48. };
  49. _proto.setContainerStyle = function setContainerStyle(containerState, container) {
  50. var style = {
  51. overflow: 'hidden'
  52. }; // we are only interested in the actual `style` here
  53. // because we will override it
  54. containerState.style = {
  55. overflow: container.style.overflow,
  56. paddingRight: container.style.paddingRight
  57. };
  58. if (containerState.overflowing) {
  59. // use computed style, here to get the real padding
  60. // to add our scrollbar width
  61. style.paddingRight = parseInt(css(container, 'paddingRight') || 0, 10) + this.scrollbarSize + "px";
  62. }
  63. css(container, style);
  64. };
  65. _proto.removeContainerStyle = function removeContainerStyle(containerState, container) {
  66. var style = containerState.style;
  67. Object.keys(style).forEach(function (key) {
  68. container.style[key] = style[key];
  69. });
  70. };
  71. _proto.add = function add(modal, container, className) {
  72. var modalIdx = this.modals.indexOf(modal);
  73. var containerIdx = this.containers.indexOf(container);
  74. if (modalIdx !== -1) {
  75. return modalIdx;
  76. }
  77. modalIdx = this.modals.length;
  78. this.modals.push(modal);
  79. if (this.hideSiblingNodes) {
  80. hideSiblings(container, modal);
  81. }
  82. if (containerIdx !== -1) {
  83. this.data[containerIdx].modals.push(modal);
  84. return modalIdx;
  85. }
  86. var data = {
  87. modals: [modal],
  88. // right now only the first modal of a container will have its classes applied
  89. classes: className ? className.split(/\s+/) : [],
  90. overflowing: isOverflowing(container)
  91. };
  92. if (this.handleContainerOverflow) {
  93. this.setContainerStyle(data, container);
  94. }
  95. data.classes.forEach(addClass.bind(null, container));
  96. this.containers.push(container);
  97. this.data.push(data);
  98. return modalIdx;
  99. };
  100. _proto.remove = function remove(modal) {
  101. var modalIdx = this.modals.indexOf(modal);
  102. if (modalIdx === -1) {
  103. return;
  104. }
  105. var containerIdx = this.containerIndexFromModal(modal);
  106. var data = this.data[containerIdx];
  107. var container = this.containers[containerIdx];
  108. data.modals.splice(data.modals.indexOf(modal), 1);
  109. this.modals.splice(modalIdx, 1); // if that was the last modal in a container,
  110. // clean up the container
  111. if (data.modals.length === 0) {
  112. data.classes.forEach(removeClass.bind(null, container));
  113. if (this.handleContainerOverflow) {
  114. this.removeContainerStyle(data, container);
  115. }
  116. if (this.hideSiblingNodes) {
  117. showSiblings(container, modal);
  118. }
  119. this.containers.splice(containerIdx, 1);
  120. this.data.splice(containerIdx, 1);
  121. } else if (this.hideSiblingNodes) {
  122. // otherwise make sure the next top modal is visible to a SR
  123. var _data$modals = data.modals[data.modals.length - 1],
  124. backdrop = _data$modals.backdrop,
  125. dialog = _data$modals.dialog;
  126. ariaHidden(false, dialog);
  127. ariaHidden(false, backdrop);
  128. }
  129. };
  130. _proto.isTopModal = function isTopModal(modal) {
  131. return !!this.modals.length && this.modals[this.modals.length - 1] === modal;
  132. };
  133. return ModalManager;
  134. }();
  135. export default ModalManager;